home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume25 / finger / part05 < prev    next >
Encoding:
Text File  |  1992-04-04  |  63.0 KB  |  2,451 lines

  1. Newsgroups: comp.sources.unix
  2. From: phil@Shiva.COM (Phil Budne)
  3. Subject: v25i168: finger - Phil's Finger Program, Part05/07
  4. Sender: unix-sources-moderator@pa.dec.com
  5. Approved: vixie@pa.dec.com
  6.  
  7. Submitted-By: phil@Shiva.COM (Phil Budne)
  8. Posting-Number: Volume 25, Issue 168
  9. Archive-Name: finger/part05
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 5 (of 7)."
  18. # Contents:  args.c autoconfig getperson.c readpr.c ttyask.c ustruct.c
  19. # Wrapped by budd@bu-it on Fri Jul  6 13:22:04 1990
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f args.c -a "${1}" != "-c" ; then 
  22.   echo shar: Will not over-write existing file \"args.c\"
  23. else
  24. echo shar: Extracting \"args.c\" \(9817 characters\)
  25. sed "s/^X//" >args.c <<'END_OF_args.c'
  26. X/*
  27. X * args.c -- process arguments for finger / whoj
  28. X * January 1986  -- Year of the Commet
  29. X *
  30. X * Copyright (C) 1986, 1990  Philip L. Budne
  31. X *
  32. X * This file is part of "Phil's Finger Program".
  33. X *
  34. X * This program is free software; you can redistribute it and/or modify
  35. X * it under the terms of the GNU General Public License as published by
  36. X * the Free Software Foundation; either version 1, or (at your option)
  37. X * any later version.
  38. X *
  39. X * This program is distributed in the hope that it will be useful,
  40. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  41. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  42. X * GNU General Public License for more details.
  43. X * 
  44. X * You should have received a copy of the GNU General Public License
  45. X * along with this program; if not, write to the Free Software
  46. X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  47. X *
  48. X */
  49. X
  50. X# ifndef lint
  51. Xstatic char *rcsid = "$Id: args.c,v 3.0 90/07/06 13:10:18 budd Rel $";
  52. X# endif /* lint not defined */
  53. X
  54. X# include <sys/types.h>
  55. X# include <strings.h>
  56. X# include <stdio.h>
  57. X# include <ctype.h>
  58. X# include <netdb.h>            /* to get cannonical name */
  59. X
  60. X# include "args.h"
  61. X# include "remote.h"
  62. X# include "finger.h"
  63. X# include "inquire.h"
  64. X
  65. Xextern dowhoj(), dofinger();        /* from output.c */
  66. Xextern void ini_select(), addlocal();    /* from select.c */
  67. Xextern BOOL have_local();        /* from select.c */
  68. Xextern void ini_tsel(), addtty();    /* from getent.c */
  69. Xextern char *ttyname();            /* from libc */
  70. Xextern void doswitch();            /* from switch.c */
  71. X
  72. XLOCAL RHOST *host_chain, *end_host_chain; /* chain of 4n hosts */
  73. XGLOBAL int netfinger;            /* input from socket */
  74. XGLOBAL BOOL useinquire;            /* have inquire database */
  75. X
  76. XLOCAL void finger();            /* forward */
  77. XLOCAL int isasocket();            /* forward */
  78. XGLOBAL void add4n();            /* forward */
  79. X
  80. XGLOBAL char localhost[ MAXHOSTLEN+1 ];    /* system /bin/hostname */
  81. XGLOBAL char officialhostname[ MAXHOSTLEN*2 ]; /* official name from host table*/
  82. XGLOBAL char OFFICIALhostname[ MAXHOSTLEN*2 ]; /* upper case copy */
  83. XGLOBAL char **aliases;            /* aliases for this host */
  84. X
  85. XGLOBAL int main( argc, argv )
  86. Xint argc;
  87. Xchar *argv[];
  88. X{
  89. X    char *prog;
  90. X    
  91. X    netfinger = isasocket(0) && isasocket(1); /* are stdin and
  92. X                           * stdout sockets (pipes)? */
  93. X
  94. X    if( !netfinger && getuid() == 0 ) {    /* if superuser */
  95. X    nice( -120 );            /* run fast */
  96. X    nice( 20 - 10 );        /* (absolute -10) */
  97. X    } /* superuser */
  98. X
  99. X    if( gethostname( localhost, MAXHOSTLEN ) == 0 ) {
  100. X    struct hostent *h;
  101. X    if( (h = gethostbyname( localhost )) != NULL ) {
  102. X        int c;
  103. X        char **a, **b;
  104. X
  105. X        strcpy( officialhostname, h->h_name );
  106. X        strupcpy( OFFICIALhostname, officialhostname );
  107. X
  108. X        c = 0;
  109. X        a = h->h_aliases;
  110. X        while( *a++ != NULL )    /* count aliases */
  111. X        c++;
  112. X
  113. X        a = h->h_aliases;
  114. X        aliases = b = (char **) calloc( c + 1, sizeof( char * ) );
  115. X        while( (*b++ = savestr( *a++ )) != NULL )
  116. X        ;
  117. X    } /* got host entry */
  118. X    } /* gethostname */
  119. X
  120. X    getterm();                /* get terminal stuff */
  121. X
  122. X    host_chain = end_host_chain = NULL;    /* clear 4n host chain */
  123. X
  124. X    if( (prog = rindex(argv[0], '/')) != NULL ) /* isolate last part of path */
  125. X    prog++;                /* skip slash */
  126. X    else
  127. X    prog = argv[0];
  128. X
  129. X    init_tsel();            /* clear tty selectors */
  130. X
  131. X    finger(prog, argc, argv);
  132. X    return( 0 );            /* ANSI conforming */
  133. X} /* main */
  134. X
  135. XLOCAL int isasocket( s )
  136. Xint s;
  137. X{
  138. X    int l;
  139. X    char sa[ 200 ];            /* bogus sockaddr struct */
  140. X
  141. X    l = sizeof( sa );            /* pass length by reference */
  142. X    if( getpeername( s, sa, &l ) < 0 )
  143. X    return( FALSE );
  144. X    else
  145. X    return( TRUE );
  146. X} /* isasocket */
  147. X
  148. XLOCAL void unswitch( str )
  149. X    char *str;
  150. X{
  151. X    register char *cp;
  152. X    if( (cp = index(str, '/')) != NULL ) {
  153. X       *cp++ = EOS;
  154. X       doswitch( cp );
  155. X   } /* found a slash */
  156. X} /* unswitch */
  157. X
  158. X
  159. XLOCAL void adduser( user )
  160. Xchar *user;
  161. X{
  162. X    char *tp;                /* char pointer */
  163. X    struct switches SavedSw;
  164. X
  165. X    for( ; user != NULL; user = rindex(user, ',') ) {
  166. X
  167. X    if( !skipwhite( &user ) )        /* remove leading white */
  168. X        continue;
  169. X
  170. X    tp = user;            /* remove trailing white */
  171. X    if( skipblack( &tp ) )        /* skip token. find EOS? */
  172. X        *tp = EOS;            /* found white -- nuke it! */
  173. X
  174. X    tp = rindex(user, '@');        /* any ATs? (reverse -- for routing) */
  175. X    if( tp != NULL ) {        /* oh goody! */
  176. X        *tp++ = EOS;        /* blast at */
  177. X        add4n( user, tp );        /* add to list of aliens */
  178. X        continue;
  179. X    }
  180. X
  181. X    SavedSw = Sw;            /* save flags */
  182. X    unswitch( user );        /* remove and process switches */
  183. X    addlocal( user );        /* process local user */
  184. X    Sw = SavedSw;            /* per user switches */
  185. X    } /* for user */
  186. X} /* adduser */
  187. X
  188. XLOCAL void finger(prog, argc, argv)
  189. Xchar *prog;
  190. Xint argc;
  191. Xchar *argv[];
  192. X{
  193. X    static char mytty[ 20 ];
  194. X    register char *cp, *tp;
  195. X
  196. X    if( strcmp(prog, "whoj") == 0 )
  197. X    sw_jobs = TRUE;
  198. X
  199. X    ini_select();            /* init selector tree etc.. */
  200. X
  201. X# ifdef INQUIRE
  202. X    useinquire = TRUE;
  203. X    if( !Mapin( NULL ) ) {        /* map in inquire database */
  204. X    useinquire = FALSE;
  205. X    fprintf( stderr, "%s\n", inq_error );
  206. X    } /* Mapin failed */
  207. X# endif /* INQUIRE defined */
  208. X
  209. X    tp = ttyname( 0 );            /* get device */
  210. X    if( tp != NULL ) {
  211. X    if( strncmp( tp, "/dev/", 5 ) == 0 )
  212. X        tp += 5;
  213. X    strcpy( mytty, tp );
  214. X    }
  215. X    else
  216. X    mytty[0] = EOS;
  217. X
  218. X# ifdef NETBERK
  219. X    if( netfinger )            /* from network? */
  220. X    sw_berkeley = TRUE;        /* be verbose if asked by name */
  221. X                    /* I hate it, but it helps aliens */
  222. X                    /* with lousy finger programs */
  223. X# endif /* NETBERK defined */
  224. X
  225. X    if( strcmp(prog, "whois") == 0 )    /* invoked as whois? */
  226. X        sw_whois = TRUE;        /* yes, set flag now */
  227. X    else if( strcmp(prog, "xf") == 0 )    /* xf? */
  228. X    sw_nosave = TRUE;        /* be nice (don't write nm file) */
  229. X
  230. X    argv++;
  231. X    argc--;
  232. X    while( argc > 0 ) {            /* while more args */
  233. X    struct switches SavedSw;
  234. X
  235. X    switch( argv[0][0] ) {
  236. X    case '-':
  237. X    case '/':            /* switch */
  238. X        doswitch( &argv[0][1] );
  239. X        break;
  240. X
  241. X    case '+':            /* tty */
  242. X        SavedSw = Sw;
  243. X        unswitch( &argv[0][1] );
  244. X        addtty( &argv[0][1] );
  245. X        Sw = SavedSw;        /* per user switches */
  246. X        break;
  247. X
  248. X    case '.':            /* just dot */
  249. X        SavedSw = Sw;
  250. X        unswitch( &argv[0][1] );
  251. X        if( argv[0][1] != EOS )
  252. X        fprintf( stderr, "%%Garbage after DOT: %s\n", &argv[0][1] );
  253. X
  254. X        if( mytty[0] != EOS )
  255. X        addtty( mytty );    /* do us. */
  256. X        else
  257. X        fprintf( stderr, "%%Could not get own terminal for '.'\n" );
  258. X        Sw = SavedSw;        /* per user switches!! */
  259. X        break;
  260. X
  261. X    case '\\':            /* quoting against local switch */
  262. X                    /* expansion? */
  263. X        adduser( argv[0]+1 );
  264. X        break;
  265. X
  266. X    default:            /* must be a user */
  267. X        adduser( argv[0] );
  268. X        break;
  269. X    } /* switch */
  270. X    argv++;
  271. X    argc--;
  272. X    } /* while argc */
  273. X
  274. X    read_conf();            /* read finger.conf */
  275. X                    /* after switches!! */
  276. X
  277. X    if( sw_jobs ) {
  278. X    dowhoj();
  279. X    return;
  280. X    }
  281. X
  282. X    if( !have_locals() && host_chain == NULL ) /* no hard work */
  283. X    dofinger( NULL );        /* show logged in users */
  284. X
  285. X    if( have_locals() ) {        /* /follow may have added locals! */
  286. X    struct switches SavedSw;
  287. X    sw_t SavedWhois;
  288. X
  289. X    SavedSw = Sw;        /* save flags */
  290. X    SavedWhois = sw_whois;
  291. X    if( sw_berkeley ) {        /* in berkley emulation mode? */
  292. X        sw_whois = TRUE;        /* yes, be verbose */
  293. X        Sw.sw_plan = !Sw.sw_noplan;
  294. X    }
  295. X
  296. X# ifdef NETFOLLOW
  297. X    if( netfinger )            /* only follow if network AND people */
  298. X        sw_follow = TRUE;
  299. X# endif /* NETFOLLOW defined */
  300. X
  301. X    select_go();            /* run locals */
  302. X
  303. X    Sw = SavedSw;            /* restore flags */
  304. X    sw_whois = SavedWhois;        /* before doing remote!! */
  305. X    } /* else */
  306. X
  307. X    if( host_chain != NULL )
  308. X    doremote( host_chain );
  309. X
  310. X} /* finger */
  311. X
  312. XLOCAL RHOST *mkrhost( name )
  313. Xchar *name;
  314. X{
  315. X    register RHOST *rh;
  316. X    if( (rh = (RHOST *)malloc( sizeof( RHOST ) )) == NULL ) {
  317. X    perror("mkrhost malloc failed");
  318. X    exit( 1 );
  319. X    } /* malloc failed */
  320. X
  321. X    rh->rh_name = name;
  322. X    rh->rh_next = NULL;
  323. X    rh->rh_user = rh->rh_endu = NULL;
  324. X
  325. X    return( rh );
  326. X} /* mkrhost */
  327. X
  328. XLOCAL RUSER *mkruser( name )
  329. Xchar *name;
  330. X{
  331. X    register RUSER *ru;
  332. X    if( (ru = (RUSER *)malloc( sizeof( RUSER ) )) == NULL ) {
  333. X    perror("mkruser malloc failed");
  334. X    exit( 1 );
  335. X    } /* malloc failed */
  336. X
  337. X    ru->ru_name = name;
  338. X    ru->ru_next = NULL;
  339. X    return( ru );
  340. X} /* mkruser */
  341. X
  342. XGLOBAL void add4n( user, host )
  343. Xchar *user, *host;
  344. X{
  345. X    if( *host == EOS ) {
  346. X    fprintf(stderr, "?Empty hostname\n");
  347. X    }
  348. X    else {                /* has host */
  349. X    register RHOST *hp;        /* host pointer */
  350. X
  351. X    for( hp = host_chain; hp != NULL; hp = hp->rh_next )
  352. X        if( strcmp(hp->rh_name, host) == 0 )
  353. X            break;
  354. X
  355. X    if( hp == NULL ) {        /* search failed */
  356. X        if( host_chain == NULL )    /* empty chain? */
  357. X            host_chain = end_host_chain = hp = mkrhost( host ); /* make1 */
  358. X        else {            /* add new host */
  359. X            hp = mkrhost( host );    /* create node */
  360. X        end_host_chain->rh_next = hp; /* add after last */
  361. X        end_host_chain = hp;    /* point end to me */
  362. X        } /* add new host */
  363. X
  364. X        hp->rh_user = hp->rh_endu = mkruser( user ); /* create usr chain */
  365. X    } /* search failed */
  366. X    else {                /* search won */
  367. X        register RUSER *up;
  368. X
  369. X        up = mkruser( user );    /* create user node */
  370. X        hp->rh_endu->ru_next = up;    /* add after last for this host */
  371. X        hp->rh_endu = up;        /* point end of list to us */
  372. X    } /* add to existing chain (search won) */
  373. X    } /* non-empty host */
  374. X
  375. X# ifdef DEBUG
  376. X    if( *user == EOS )
  377. X        printf(" @%s\n", host);
  378. X    else
  379. X        printf("%s@%s\n", user, host);
  380. X# endif /* DEBUG defined */
  381. X} /* add 4n */
  382. X
  383. XGLOBAL BOOL islocalhost( s )
  384. X    char *s;
  385. X{
  386. X    struct hostent *h;
  387. X    char **a;
  388. X
  389. X    if( strcmp( s, officialhostname ) == 0 || strcmp( s, localhost ) == 0 )
  390. X    return( TRUE );
  391. X
  392. X    a = aliases;
  393. X    while( *a != NULL )
  394. X    if( strcmp( s, *a++ ) == 0 )
  395. X        return( TRUE );
  396. X
  397. X    if( (h = gethostbyname( s )) == NULL )
  398. X    return( FALSE );
  399. X
  400. X    if( strcmp( h->h_name, officialhostname ) == 0 )
  401. X    return( TRUE );
  402. X
  403. X    return( FALSE );
  404. X} /* islocalhost */
  405. X
  406. X/*
  407. X * Local variables:
  408. X * comment-column: 40
  409. X * End:
  410. X */
  411. END_OF_args.c
  412. if test 9817 -ne `wc -c <args.c`; then
  413.     echo shar: \"args.c\" unpacked with wrong size!
  414. fi
  415. # end of overwriting check
  416. fi
  417. if test -f autoconfig -a "${1}" != "-c" ; then 
  418.   echo shar: Will not over-write existing file \"autoconfig\"
  419. else
  420. echo shar: Extracting \"autoconfig\" \(10695 characters\)
  421. sed "s/^X//" >autoconfig <<'END_OF_autoconfig'
  422. X#! /bin/sh
  423. X#  
  424. X# Automatic configuration shell script for finger
  425. X# Not quite up to Larry Wall's level...
  426. X#  
  427. X# Copyright (C) 1988, 1990  Philip L. Budne
  428. X#  
  429. X# This file is part of "Phil's Finger Program".
  430. X#  
  431. X# This program is free software; you can redistribute it and/or modify
  432. X# it under the terms of the GNU General Public License as published by
  433. X# the Free Software Foundation; either version 1, or (at your option)
  434. X# any later version.
  435. X#  
  436. X
  437. X# $Id: autoconfig,v 3.0 90/07/06 13:10:22 budd Rel $
  438. X
  439. X#  
  440. X#  
  441. XTMPDIR=/tmp
  442. X#  
  443. XSYSTEM=''
  444. X#  
  445. XE=/bin/echo
  446. X#  
  447. X# blank line
  448. XB=$E
  449. X#  
  450. X# should return status
  451. XCONTAINS=grep
  452. X#  
  453. X# hope its on your path, or built in
  454. XT=test
  455. X# end test
  456. XET=
  457. X#  
  458. X# test flags:
  459. X#  
  460. X# existance 
  461. XEXI=-f
  462. X# directory 
  463. XDIR=-d
  464. X# negation 
  465. XNOT=!
  466. X#  
  467. XOR=-o
  468. XAND=-a
  469. XSTR=
  470. XLP='('
  471. XRP=')'
  472. X#  
  473. X# S5
  474. XBLK=-b
  475. XCHR=-c
  476. X# also -f means regular file only!
  477. X#  
  478. X# shorthand...
  479. XTEXI="$T $EXI"
  480. XTSTR="$T $STR"
  481. XTDIR="$T $DIR"
  482. X#
  483. Xif $TEXI /bin/hostname $ET; then
  484. X    HOSTNAME=`/bin/hostname`
  485. Xelif $TEXI /bin/uname $ET; then
  486. X    HOSTNAME=`/bin/uname -n`
  487. Xelse
  488. X    HOSTNAME='idunno'
  489. Xfi
  490. X#  
  491. X$E '/*'
  492. X$E ' *    local.h for '$HOSTNAME
  493. X$E ' *    created on '`date` by `./mywhoami` using autoconfig
  494. X$E ' *'
  495. X$E ' * do not edit this file.  instead put #define and #undef lines'
  496. X$E ' * in the file local-flags which is inserted at the end of this file.'
  497. X$E ' */'
  498. X$B
  499. X################
  500. Xif $TEXI /bin/sun $ET && /bin/sun; then
  501. X    # check for /usr/lib/liblwp.a ?
  502. X    if $TDIR /var $ET; then
  503. X    if $TEXI /bin/uname $ET; then
  504. X        SOS=`uname -r -v | sed -e 's/\.//g' -e 's/ //g'`
  505. X    elif $TDIR /usr/kvm $ET; then
  506. X        # consdev fixed/broken in 4.0.3
  507. X        SOS=403
  508. X    else
  509. X        SOS=400
  510. X    fi
  511. X    else
  512. X    # 3.something
  513. X    SOS=300
  514. X    fi
  515. X    $E '# define SunOS '$SOS
  516. X    $B
  517. Xelif $TEXI /Umax.image $ET; then
  518. X    if $TDIR /var $ET; then
  519. X    $E '# define Umax 43            /* Encore Umax 4.3 */'
  520. X    else
  521. X        $E '# define Umax 42            /* Encore Umax 4.2 */'
  522. X    fi
  523. X    $B
  524. Xelif $CONTAINS BSD4_3 /usr/include/sys/param.h > /dev/null; then
  525. X    $E '# define bsd4_3'
  526. X    $B
  527. Xfi
  528. X# accel, ultrix cpp have predefines
  529. X################
  530. X# Sun, A/UX
  531. Xif $TEXI /etc/in.rlogind $OR $EXI /usr/etc/in.rlogind $ET; then
  532. X    $E '# define IN_DOT_DAEMON    /* internet daemon names prefixed with in. */'
  533. X    $B
  534. Xfi
  535. X################
  536. X# check for /usr/adm/lastlog as well?
  537. Xif $TEXI /usr/include/lastlog.h $ET; then
  538. X    $E '# define LASTLOG            /* BSD last login file */'
  539. X    $B
  540. Xfi
  541. X################
  542. X# check libc.a for wait3??
  543. Xif $T $NOT $EXI /usr/include/sys/wait.h $ET; then
  544. X    $E '# define NO_WAIT_H            /* no BSD sys/wait.h */'
  545. X    $B
  546. Xfi
  547. X################
  548. X# BSD systems have drum
  549. X# use checkmode to avoid incompatabilities in test
  550. X# RT AIX and UmaxV lack /dev/swap
  551. Xif ./checkmode /dev/drum 0 >/dev/null 2>&1; then
  552. X    $E '# define SWAP_DEVICE "/dev/drum"    /* swap device */'
  553. X    $B
  554. Xelif ./checkmode /dev/swap 0 >/dev/null 2>&1; then
  555. X    $E '# define SWAP_DEVICE "/dev/swap"    /* swap device */'
  556. X    $B
  557. X    USG=true
  558. Xelif $T $CHR /dev/ipldevice $ET; then
  559. X    $E '# define AIX3                /* AIX release 3 (RS/6000) */'
  560. X    USG=true
  561. Xelif $TEXI /bin/vrmfmt $ET; then
  562. X    # AIX defined by cc command (what about PS/2 AIX?)
  563. X    USG=true
  564. X    UNDERSCORE=true
  565. X    $E '# define AIX_RT                /* IBM PC/RT AIX */'
  566. X    $B
  567. Xelif $T $CHR /dev/bbram $ET; then
  568. X    $E '# define UmaxV                /* Encore Umax V */'
  569. X    $B
  570. X    USG=true
  571. X    UNDERSCORE=true
  572. Xelif $TEXI /usr/include/sys/sysi86.h $ET; then
  573. X    # Interactive SVR3.2 (others?)
  574. X    USG=true
  575. X    $E '# define SYSI86                /* 386/ix */'
  576. X    $B
  577. Xfi
  578. X####
  579. Xif $TSTR "$USG" $ET; then
  580. X    $E '# define USG                /* AT&T Unix */'
  581. X    $B
  582. X    if $T $CHR /dev/pts1 $ET; then
  583. X    # AIX at least...
  584. X    $E '# define PTYPATH "/dev/pts1"'
  585. X    $B
  586. X    $E '# define PTS_PTY_NAMES'
  587. X    $B    
  588. X    elif $T $CHR /dev/ttyq1 $ET; then
  589. X    # SGI at least...
  590. X    $E '# define PTYPATH "/dev/ttyq1"'
  591. X    $B
  592. X    fi
  593. X    if $TEXI /usr/include/sys/dir.h $ET; then
  594. X    $E '# define DIR_H'
  595. X    $B
  596. X    fi
  597. X    if $TEXI /usr/include/sys/i386/ps2mous.h $ET; then
  598. X    $E '# define AIX_PS2'
  599. X    $B
  600. X    fi
  601. Xfi
  602. X################
  603. Xif $TEXI /usr/include/filehdr.h $ET; then
  604. X    $E '# define COFF                /* Common Object File Fiasco */'
  605. X    $B
  606. Xelse
  607. X    UNDERSCORE=true
  608. Xfi
  609. X####
  610. Xif $TSTR "$UNDERSCORE"; then
  611. X    $E '# define UNDERSCORE_NLIST_NAMES'
  612. X    $B
  613. Xfi
  614. X################
  615. X# SOS3.4 has (empty) stream.h!
  616. Xif $TEXI /usr/include/sys/stropts.h $ET; then
  617. X    $E '# define STREAMS'
  618. X    $B
  619. Xfi
  620. X################
  621. X# check for SVR3 state names
  622. Xif $CONTAINS SXBRK /usr/include/sys/proc.h >/dev/null; then
  623. X    $E '# define SVR3_STATES'
  624. X    $B
  625. Xfi
  626. X################
  627. X# check for short *{u,p}_ttyp (streams tty driver) sgi and SOS4
  628. Xif $CONTAINS 'short[     ]*\*[     ]*[ups]_ttyp' \
  629. X    /usr/include/sys/user.h /usr/include/sys/proc.h >/dev/null 2>&1 ||
  630. X    $TEXI /usr/include/sys/session.h $ET; then
  631. X    $E '# define SHORT_TTYP'
  632. X    $B
  633. Xfi
  634. X################
  635. X# p_addr on AOS/ACIS 4.3 (RT) loses
  636. Xif $TDIR /usr/ibm $ET; then
  637. X    $E '# define NEED_USRPT'
  638. X    $B
  639. Xfi
  640. X################
  641. X# USG uname(2) call (or simulation)
  642. X# perhaps grep nm of libc.a too?
  643. Xif $TEXI /usr/include/sys/utsname.h $ET; then
  644. X    $E '# define UTSNAME            /* USG uname(2) call */'
  645. X    $B
  646. Xfi
  647. X################
  648. Xif $T $NOT $EXI /usr/include/strings.h $ET; then
  649. X    $E '# define NO_STRINGS_H            /* No BSD strings */'
  650. X    $B
  651. Xfi
  652. X################
  653. XLIB=/lib/libc.a
  654. XLIBNM=/tmp/auto$$
  655. Xif $TEXI /usr/include/netdb.h $ET && \
  656. X    $CONTAINS h_errno /usr/include/netdb.h >/dev/null; then
  657. X    $E "netdb.h has h_errno.  Checking libc.a..." 1>&2
  658. X    nm $LIB > $LIBNM
  659. X    if $CONTAINS 'h_errlist' $LIBNM >/dev/null; then
  660. X    $E "The world is safe! $LIB contains h_errlist" 1>&2
  661. X    $E '# define HAVE_H_ERRNO            /* found h_errno */'
  662. X    else
  663. X# SunOS 4.0 strikes again!
  664. X    $E "$LIB lacks h_errlist!!" 1>&2
  665. X    fi
  666. X    $B
  667. X    rm -f $LIBNM
  668. Xfi
  669. X################
  670. Xif $TEXI /bin/write $ET; then
  671. X    if ./checkmode /bin/write gs >/dev/null; then
  672. X    set foo `./getgroup /bin/write`
  673. X    $E "# define TTY_GROUP_NUMBER $3"
  674. X    $B
  675. X    if $TSTR "$4" $ET; then
  676. X        $E '# define TTY_GROUP "'$4'"'
  677. X        $B
  678. X    fi
  679. X    fi
  680. Xfi
  681. X################
  682. X# for Install.cpp -- shell orif to avoid confusing BSD test with -c
  683. X# check for protected swap device as well??
  684. Xif $TEXI /dev/kmem $ET || $T $CHR /dev/kmem $ET; then
  685. X    if ./checkmode /dev/kmem gr+o gr >/dev/null; then
  686. X    $E '/* for Install.cpp */'
  687. X    set foo `./getgroup /dev/kmem`
  688. X    if $TSTR "$4" $ET; then
  689. X        $E "# define KMEM_GROUP $4"
  690. X    else
  691. X        $E "# define KMEM_GROUP $3"
  692. X    fi
  693. X    $B
  694. X    fi
  695. Xfi
  696. X################
  697. Xif $TEXI /bin/domainname $ET; then
  698. X    YPDOMAIN=`/bin/domainname`
  699. Xelif $TEXI /usr/bin/domainname $ET; then
  700. X    YPDOMAIN=`/usr/bin/domainname`
  701. Xfi
  702. X################
  703. Xif $TEXI /etc/ypbind $OR $EXI /usr/etc/ypbind $ET; then
  704. X    if $TSTR "$YPDOMAIN" $ET; then
  705. X    $E "IF YOU ARE NOT USING YP, YOU MAY NEED TO DEFINE 'GETPWNAM_SLOW'"\
  706. X                                1>&2
  707. X    $E '/* getpwnam(3) is fast (yellow pages) */'
  708. X    else
  709. X    $E "IF YOU ARE USING YP, YOU MAY WANT TO UNDEFINE 'GETPWNAM_SLOW'"\
  710. X                                1>&2
  711. X    $E '# define GETPWNAM_SLOW            /* yp not enabled */'
  712. X    fi
  713. Xelif $TEXI /etc/passwd.pag $OR $EXI /etc/passwd.dir $ET; then
  714. X    $E '/* getpwnam(3) is fast (dbm passwd file) */'
  715. Xelse
  716. X    $E '# define GETPWNAM_SLOW            /* 4.2 getpwnam(3) is losing */'
  717. Xfi
  718. X$B
  719. X################
  720. X# should check libc.a for yp_match.o
  721. Xif $TEXI /usr/include/rpcsvc/ypclnt.h $AND $STR "$YPDOMAIN" $ET; then
  722. X    $E '# define HAVE_YP_MATCH            /* have yp_match(3) */'
  723. X    $B
  724. Xfi
  725. X################
  726. Xif $TEXI /etc/aliases $ET; then
  727. X    ALIASES=/etc/aliases
  728. Xelif $TEXI /usr/lib/aliases $ET; then
  729. X    ALIASES=/usr/lib/aliases
  730. Xfi
  731. X#  
  732. Xif $TSTR "$ALIASES" $ET; then
  733. X    $E '# define ALIASES "'$ALIASES'"    /* sendmail aliases file */'
  734. X    $B
  735. Xfi
  736. X################
  737. X# 4.3 and Ultrix
  738. X# note: use exists. let them see grep error!
  739. Xif $TEXI /usr/include/sys/tty.h $ET; then
  740. X    if $CONTAINS t_winsize /usr/include/sys/tty.h >/dev/null; then
  741. X    $E '# define TTY_REQUIRES_IOCTL        /* struct winsize */'
  742. X    $B
  743. X    fi
  744. Xfi
  745. X################
  746. X# 4.3 and Ultrix
  747. X# perhaps search libc.a too?
  748. Xif $TEXI /usr/include/ttyent.h $ET; then
  749. X    $E '# define TTYENT                /* use getttyent(3) */'
  750. X    $B
  751. Xfi
  752. X################
  753. X# 4.3, Ultrix and Sun
  754. Xif $TEXI /etc/inetd $OR $EXI /usr/etc/inetd $ET; then
  755. X    $E '# define INETD                /* use inetd for fingerd */'
  756. X    $B
  757. Xfi
  758. X################
  759. X# SunOS 4.x, Ultrix 3.x, SVR3?
  760. Xif $CONTAINS 'void.*signal' /usr/include/signal.h >/dev/null; then
  761. X    $E '# define VOIDSIG            /* signal() declared as void * */'
  762. X    $B
  763. Xfi
  764. X################
  765. X# Ultrix 3.x, A/UX
  766. Xif $CONTAINS p_ttyp /usr/include/sys/proc.h >/dev/null; then
  767. X    $E '# define P_TTYP                /* tty pointer in proc struct */'
  768. X    $B
  769. Xfi
  770. X################
  771. X# USG 
  772. Xif $CONTAINS ut_host /usr/include/utmp.h >/dev/null; then
  773. X    $E '/* utmp has ut_host field */'
  774. Xelse
  775. X    $E '# define UTMP_NO_HOST            /* utmp file lacks host field */'
  776. Xfi
  777. X$B
  778. X################
  779. Xif $TEXI /vmunix $ET; then
  780. X    $E '# define KERNEL_FILE "/vmunix"'
  781. Xelif $TEXI /unix $ET; then
  782. X    $E '# define KERNEL_FILE "/unix"'
  783. Xelif $TEXI /dynix $ET; then
  784. X    $E '# define KERNEL_FILE "/dynix"'
  785. Xelif $TEXI /Umax.image $ET; then
  786. X    $E '# define KERNEL_FILE "/Umax.image"'
  787. Xelse
  788. X    $E '/* no KERNEL_FILE found */'
  789. Xfi
  790. X$B
  791. X################
  792. X# AIX has both?  check /usr/mail first!!
  793. Xif $TDIR /usr/mail $ET; then
  794. X    $E '# define MAIL_SPOOL "/usr/mail"'
  795. Xelif $TDIR /usr/spool/mail $ET; then
  796. X    $E '# define MAIL_SPOOL "/usr/spool/mail"'
  797. Xelse
  798. X    $E '/* no MAIL_SPOOL found */'
  799. Xfi
  800. X$B
  801. X################
  802. Xif $TEXI /usr/include/syslog.h $ET; then
  803. X    $E '# define SYSLOG                /* fingerd does syslog-ing */'
  804. X    $B
  805. Xfi
  806. X################
  807. Xif $TEXI /usr/include/inquir.h $ET; then
  808. X    $E '# define INQUIRE            /* use inquire database */'
  809. X    $B
  810. Xfi
  811. X
  812. X# Boilerplate...
  813. Xcat <<END_OF_STUFF
  814. X# define SAVED_NLIST "/etc/finger-saved-nlist" /* save nlist to this file */
  815. X
  816. X# define AUTONLIST            /* update nlist save file as needed */
  817. X
  818. X# define NLIST_MODE 0664        /* creation mode for nlist file */
  819. X
  820. X# define NETBERK            /* network finger implies /berk */
  821. X                    /* (I hate this) */
  822. X
  823. X# define NETFOLLOW            /* net finger implies /follow */
  824. X
  825. X/**************** REQUIRED!! (used by Install) ****************/
  826. X
  827. X# define TTYLOC_DIR "/usr/spool/ttyloc"
  828. X
  829. X# define TTYLOC_MODE 0644
  830. X
  831. XEND_OF_STUFF
  832. X#  
  833. Xif $TEXI local-flags $ET; then
  834. X    $E '/* local-flags: *****************/'
  835. X    cat local-flags
  836. X    $B
  837. X    $E '/* end of local-flags ***********/'
  838. Xelse
  839. X    $E '/* host name prefixes to remove */'
  840. X    $E '/*# define PREFIXES "PREFIX1", "PFX2" /**/'
  841. X    $B
  842. X    $E '/* extra paths to try to exec finger */'
  843. X    $E '/* # define FINGERPATHS "/usr/local/local/bin/finger", "/bin/who" /**/'
  844. X    $B
  845. X    $E '# define C_FLAGS -g        /* compiler debug on by default */'
  846. X    $E '# define DEBUGSW        /* include /debug switch */'
  847. X    $E '# define UNPREFIX_NODOMAIN    /* unprefix hosts with no dots */'
  848. Xfi
  849. X$B
  850. Xcat <<END_OF_STUFF
  851. X/*
  852. X * Local variables:
  853. X * comment-column: 40
  854. X * End:
  855. X */
  856. XEND_OF_STUFF
  857. END_OF_autoconfig
  858. if test 10695 -ne `wc -c <autoconfig`; then
  859.     echo shar: \"autoconfig\" unpacked with wrong size!
  860. fi
  861. chmod +x autoconfig
  862. # end of overwriting check
  863. fi
  864. if test -f getperson.c -a "${1}" != "-c" ; then 
  865.   echo shar: Will not over-write existing file \"getperson.c\"
  866. else
  867. echo shar: Extracting \"getperson.c\" \(9142 characters\)
  868. sed "s/^X//" >getperson.c <<'END_OF_getperson.c'
  869. X/*
  870. X * getperson.c -- read person oriented data (December 1985)
  871. X *
  872. X * Copyright (C) 1986, 1990  Philip L. Budne
  873. X *
  874. X * This file is part of "Phil's Finger Program".
  875. X *
  876. X * This program is free software; you can redistribute it and/or modify
  877. X * it under the terms of the GNU General Public License as published by
  878. X * the Free Software Foundation; either version 1, or (at your option)
  879. X * any later version.
  880. X *
  881. X */
  882. X
  883. X# ifndef lint
  884. Xstatic char *rcsid = "$Id: getperson.c,v 3.0 90/07/06 13:10:51 budd Rel $";
  885. X# endif /* lint not defined */
  886. X
  887. X# include <sys/types.h>
  888. X# include <strings.h>
  889. X# include <ctype.h>
  890. X# include <stdio.h>
  891. X# include <pwd.h>            /* getpwent defns */
  892. X# ifdef INQUIRE
  893. X# include <inquir.h>
  894. X# endif /* INQUIRE defined */
  895. X# include "person.h"
  896. X# include "args.h"            /* before luser.h */
  897. X# include "luser.h"
  898. X# include "finger.h"
  899. X
  900. X# ifndef DEFSHELL
  901. X# define DEFSHELL "/bin/csh"        /* dull shell */
  902. X# endif /* DEFSHELL not defined */
  903. X
  904. X# ifndef PRJLEN
  905. X# define PRJLEN 70            /* max lex for project */
  906. X# endif /* PRJLEN not defined */
  907. X
  908. Xextern char *strip();            /* from string.c */
  909. Xextern BOOL useinquire;
  910. X
  911. XPERSON *makeperson();            /* forward... */
  912. X
  913. XGLOBAL int treesize( t )        /* count entries in a tree */
  914. Xregister LUSER *t;
  915. X{
  916. X    if( t == NULL )
  917. X    return( 0 );
  918. X    else
  919. X    return( treesize( t->u_left ) + treesize( t->u_right ) + 1 );
  920. X}
  921. X
  922. XGLOBAL LUSER *treefind(t, uname)    /* find uname in tree */
  923. Xregister LUSER *t;
  924. Xchar *uname;
  925. X{
  926. X    register int compare;
  927. X
  928. X    while( t != NULL ) {
  929. X# ifdef DEBUG
  930. X    printf(" tf '%s' ", uname );
  931. X    fflush(stdout);
  932. X    printf(" '%s'", t->u_user );
  933. X    fflush(stdout);
  934. X# endif /* DEBUG defined */
  935. X        compare = strcmp(uname, t->u_user); /* do compare once */
  936. X# ifdef DEBUG
  937. X    printf(" %d\n", compare );
  938. X# endif /* DEBUG defined */
  939. X    if( compare > 0 )
  940. X        t = t->u_right;
  941. X    else if( compare < 0 )
  942. X        t = t->u_left;
  943. X    else
  944. X        return( t );
  945. X    }
  946. X    return( NULL );
  947. X} /* treefind */
  948. X
  949. X# ifdef GETPWNAM_SLOW
  950. XGLOBAL int pwtree( t )            /* get pw entries for whole tree */
  951. XLTREE *t;
  952. X{
  953. X    register struct passwd *pw;
  954. X    int size, todo;            /* number of tree entries */
  955. X
  956. X    size = todo = treesize( t );    /* get entries in tree */
  957. X    if( todo == 0 )
  958. X    return( 0 );            /* nothing to do! */
  959. X
  960. X    setpwent();
  961. X    while( todo > 0  &&  (pw = getpwent()) != NULL ) { /* for each pwentry */
  962. X                    /* search in tree for this uname */
  963. X                    /* if found, create a person struct */
  964. X                    /* and look for multiple logins */
  965. X
  966. X    register LUSER *tp;
  967. X    register PERSON *pp;
  968. X
  969. X# ifdef DEBUG
  970. X    printf("pwtree(%d): %s\n", todo, pw->pw_name );
  971. X# endif /* DEBUG defined */
  972. X
  973. X    tp = t;                /* get root of tree */
  974. X    pp = NULL;            /* no person entry created yet */
  975. X
  976. X    tp = treefind(tp, pw->pw_name); /* lookup user in tree */
  977. X    while( todo > 0  &&  tp != NULL ) {
  978. X        if( tp->u_person != NULL )    /* already have person? */
  979. X        break;            /* must be is passwd twice! (or yp) */
  980. X
  981. X        todo--;            /* one less to do */
  982. X# ifdef DEBUG
  983. X        printf(" ** %s **\n", tp->u_user );
  984. X# endif /* DEBUG defined */
  985. X        if( pp == NULL )        /* created a person yet? */
  986. X            pp = makeperson(tp,pw,NULL); /* do it now. */
  987. X        pp->p_count++;        /* bump use count */
  988. X        tp->u_person = pp;        /* point user to person */
  989. X        tp = treefind(tp->u_right, pw->pw_name); /* lookup again */
  990. X                    /* assumes that dupes are added */
  991. X                    /* to right side (.see insert)*/
  992. X    } /* while tp != NULL */
  993. X    } /* while getpwent */
  994. X    endpwent();
  995. X    return( size );
  996. X} /* pwtree */
  997. X# else  /* GETPWNAM_SLOW not defined */
  998. XLOCAL int pwtree2_count;        /* ah for pascal */
  999. XLOCAL void pwtree2();            /* forward */
  1000. X
  1001. XGLOBAL int pwtree( t )
  1002. XLTREE *t;
  1003. X{
  1004. X    setpwent();                /* getpwnam does set/end */
  1005. X                    /* so this is a noop */
  1006. X    pwtree2_count = 0;
  1007. X    pwtree2( t );
  1008. X    endpwent();
  1009. X    return( pwtree2_count );
  1010. X} /* pwtree */
  1011. X
  1012. XLOCAL void pwtree2( t )            /* fill in person entries */
  1013. XLTREE *t;                /* using getpwnam */
  1014. X{    
  1015. X    register struct passwd *pw;
  1016. X    register LUSER *tp;
  1017. X    register PERSON *pp;
  1018. X
  1019. X# ifdef DEBUG
  1020. X    printf("pwtree2(%d): %s\n", todo, pw->pw_name );
  1021. X# endif /* DEBUG defined */
  1022. X
  1023. X    tp = (LUSER *)t;            /* get root of tree */
  1024. X    pp = NULL;                /* no person entry created yet */
  1025. X
  1026. X    if( tp == NULL )
  1027. X    return;
  1028. X
  1029. X    while( tp != NULL && tp->u_person == NULL ) {
  1030. X    if( pp == NULL ) {        /* created a person yet? */
  1031. X        if( (pw = getpwnam( tp->u_user )) == NULL )
  1032. X        break;
  1033. X        pp = makeperson(tp,pw,NULL); /* do it now. */
  1034. X    }
  1035. X    pp->p_count++;            /* bump use count */
  1036. X    pwtree2_count++;
  1037. X    tp->u_person = pp;        /* point user to person */
  1038. X    tp = treefind(tp->u_right, pw->pw_name); /* lookup again */
  1039. X                    /* assumes that dupes are added */
  1040. X                    /* to right side (.see insert)*/
  1041. X    } /* while tp != NULL */
  1042. X
  1043. X    pwtree2( t->u_right );
  1044. X    pwtree2( t->u_left );
  1045. X
  1046. X} /* pwtree2 */
  1047. X# endif /* GETPWNAM_SLOW not defined */
  1048. X
  1049. XGLOBAL PERSON *makeperson( up, pw, inq )
  1050. XLUSER *up;
  1051. Xstruct passwd *pw;
  1052. Xstruct info *inq;
  1053. X{
  1054. X    char fname[100], pbuf[ PLEN+1 ];
  1055. X    register PERSON *pp;
  1056. X    register char *dp;
  1057. X    register int i;
  1058. X    char *sp;
  1059. X    int file;
  1060. X
  1061. X    if( (pp = (PERSON *) malloc( sizeof( PERSON ) )) == NULL )
  1062. X    return( NULL );
  1063. X
  1064. X    pp->p_count = 0;
  1065. X    pp->p_flags = 0;            /* clear flags */
  1066. X    pp->p_waddr = pp->p_wphone = pp->p_hphone = pp->p_haddr = NULL;
  1067. X    pp->p_birthday = pp->p_supervisor = pp->p_project = pp->p_nickname = NULL;
  1068. X    pp->p_maddr = pp->p_personal = pp->p_home = NULL;
  1069. X    pp->p_remarks = pp->p_shell = NULL;
  1070. X    pp->p_group = pp->p_relation = ' ';
  1071. X
  1072. X    if( pw != NULL ) {            /* !! */
  1073. X    pp->p_uid = pw->pw_uid;        /* copy user id */
  1074. X    pp->p_gid = pw->pw_gid;        /* copy group id */
  1075. X    pp->p_home = savestr( pw->pw_dir ); /* home directory */
  1076. X
  1077. X    maddr( pp, pw->pw_name );    /* get mailing address */
  1078. X
  1079. X    sp = pw->pw_gecos;        /* source pointer */
  1080. X    if( strcmp(sp, "RC") == 0 ) {    /* gecos == "RC" */
  1081. X        pp->p_flags |= P_RC;    /* flag it */
  1082. X        return( pp );
  1083. X    } /* RC */
  1084. X    }
  1085. X    else
  1086. X    pp->p_flags |= P_NOPWENT;
  1087. X
  1088. X# ifdef INQUIRE
  1089. X    if( pw != NULL )
  1090. X    name = pw->pw_name;
  1091. X    else                /* seems unlikely, but */
  1092. X    name = up->u_user;        /* of use when yp kaput! */
  1093. X    if( useinquire && doinquire( name, pp, inq ) ) /* check holmes database */
  1094. X    pp->p_flags |= P_INQUIRE;    /* flag it */
  1095. X# else  /* INQUIRE not defined */
  1096. X    acct_group( pp );
  1097. X# endif /* INQUIRE not defined */
  1098. X
  1099. X    if( pw != NULL && pp->p_personal == NULL ) {
  1100. X    dp = pbuf;            /* pointer to dest */
  1101. X    for( i = 0; i < PLEN; i++ ) {    /* for max len of personal name */
  1102. X        if( *sp == EOS || *sp == ',' )
  1103. X        break;
  1104. X        if( *sp == '&' ) {        /* sigh, handle ampersand crock */
  1105. X        register char *unp;    /* uname pointer */
  1106. X        unp = pw->pw_name;    /* get pointer to user name */
  1107. X        if( islower( *unp ) && (i == 0 || isspace(sp[-1])) ) {
  1108. X            *dp++ = toupper( *unp );
  1109. X            unp++;        /* avoid side effect as macro arg */
  1110. X            i++;
  1111. X        } /* first char is lower */
  1112. X
  1113. X        while( i < PLEN && *unp != NULL ) { /* copy it in */
  1114. X            i++;
  1115. X            *dp++ = *unp++;
  1116. X        } /* while */
  1117. X        sp++;
  1118. X        } /* & */
  1119. X        else
  1120. X        *dp++ = *sp++;
  1121. X    } /* for i */
  1122. X    *dp = EOS;
  1123. X    pp->p_personal = savestr( pbuf );
  1124. X    } /* have pw entry, no personal name */
  1125. X
  1126. X    if( !sw_whois )            /* **** doing full? **** */
  1127. X    return( pp );            /* no, quit now */
  1128. X
  1129. X    if( pw != NULL &&
  1130. X       (pp->p_waddr == NULL ||
  1131. X    pp->p_wphone == NULL || pp->p_hphone == NULL ) ) {
  1132. X
  1133. X    /* BUG: handle USG format gecos data */
  1134. X    sp = index(pw->pw_gecos, ',');    /* anything after user? */
  1135. X    while( sp != NULL ) {        /* radioactive waste *BOGUS LOOP* */
  1136. X        sp++;            /* skip comma */
  1137. X
  1138. X        if( !skipwhite( &sp ) )
  1139. X        break;            /* break bogus loop */
  1140. X                    /* avoids harmful goto! */
  1141. X        dp = index(sp, ',');
  1142. X        if( dp != NULL )
  1143. X        *dp++ = EOS;
  1144. X        sp = strip( sp );
  1145. X        if( pp->p_waddr == NULL && strlen( sp ) > 0 )
  1146. X        pp->p_waddr = savestr( office( sp ) );
  1147. X        if( dp == NULL )
  1148. X        break;            /* break bogus loop */
  1149. X
  1150. X        sp = dp;
  1151. X        if( !skipwhite( &sp ) )
  1152. X        break;            /* break bogus loop */
  1153. X
  1154. X        dp = index(sp, ',');
  1155. X        if( dp != NULL )
  1156. X        *dp++ = EOS;
  1157. X        sp = strip( sp );
  1158. X        if( *sp != EOS )
  1159. X        if( pp->p_wphone == NULL )
  1160. X            pp->p_wphone = savestr( sp );
  1161. X
  1162. X        if( dp == NULL )
  1163. X        break;            /* break bogus loop */
  1164. X
  1165. X        sp = dp;
  1166. X        if( !skipwhite( &sp ) )
  1167. X        break;            /* break bogus loop */
  1168. X
  1169. X        sp = strip( sp );
  1170. X        if( *sp != EOS )
  1171. X        if( pp->p_hphone == NULL )
  1172. X            pp->p_hphone = savestr( sp );
  1173. X
  1174. X        break;            /* break bogus loop */
  1175. X    } /* process radioactive waste (gecos) */
  1176. X    } /* pw entry & missing info from GECOS */
  1177. X
  1178. X    if( pw != NULL ) {
  1179. X    if( strcmp(pw->pw_shell, DEFSHELL) != 0 )
  1180. X        pp->p_shell = savestr( pw->pw_shell );
  1181. X    else
  1182. X        pp->p_shell = NULL;
  1183. X    
  1184. X    if( pp->p_project == NULL ) {
  1185. X        strcpy(fname, pp->p_home);
  1186. X        strcat(fname, "/.project");
  1187. X        while( (file = open(fname, 0)) >= 0 ) {
  1188. X        char prjbuf[PRJLEN];
  1189. X        char *cp;
  1190. X        int cc;
  1191. X        
  1192. X        cc = read(file, prjbuf, PRJLEN-1);
  1193. X        close(file);
  1194. X        if( cc < 1 )
  1195. X            break;        /* leave bogus loop */
  1196. X        prjbuf[cc] = EOS;
  1197. X        
  1198. X        if( (cp = index(prjbuf, '\n')) != NULL )
  1199. X            *cp = EOS;
  1200. X        
  1201. X        cp = strip( prjbuf );
  1202. X        if( *cp != EOS )
  1203. X            pp->p_project = savestr( cp );
  1204. X        break;        /* leave bogus loop */
  1205. X        } /* found project */
  1206. X    } /* look at .project file */
  1207. X    } /* have pw entry */
  1208. X    return( pp );
  1209. X} /* makeperson */
  1210. X
  1211. X/*
  1212. X * Local variables:
  1213. X * comment-column: 40
  1214. X * End:
  1215. X */
  1216. END_OF_getperson.c
  1217. if test 9142 -ne `wc -c <getperson.c`; then
  1218.     echo shar: \"getperson.c\" unpacked with wrong size!
  1219. fi
  1220. # end of overwriting check
  1221. fi
  1222. if test -f readpr.c -a "${1}" != "-c" ; then 
  1223.   echo shar: Will not over-write existing file \"readpr.c\"
  1224. else
  1225. echo shar: Extracting \"readpr.c\" \(9509 characters\)
  1226. sed "s/^X//" >readpr.c <<'END_OF_readpr.c'
  1227. X/*
  1228. X * readpr.c -- read process table
  1229. X *
  1230. X * Copyright (C) 1986, 1990  Philip L. Budne
  1231. X *
  1232. X * This file is part of "Phil's Finger Program".
  1233. X *
  1234. X * This program is free software; you can redistribute it and/or modify
  1235. X * it under the terms of the GNU General Public License as published by
  1236. X * the Free Software Foundation; either version 1, or (at your option)
  1237. X * any later version.
  1238. X *
  1239. X */
  1240. X
  1241. X# ifndef lint
  1242. Xstatic char *rcsid = "$Id: readpr.c,v 3.0 90/07/06 13:11:38 budd Rel $";
  1243. X# endif /* lint not defined */
  1244. X
  1245. X# include "finger.h"
  1246. X# include "waitstate.h"
  1247. X# ifndef Umax
  1248. X
  1249. X# include <stdio.h>
  1250. X# include "ustruct.h"
  1251. X
  1252. X# ifdef USG
  1253. X# include <sys/var.h>
  1254. X# endif /* USG defined */
  1255. X
  1256. X# ifndef SIGHUP
  1257. X# include <signal.h>
  1258. X# endif /* SIGHUP not defined */
  1259. X
  1260. X# include "pr.h"
  1261. X# include "kmem.h"
  1262. X# include "info.h"            /* after finger.h */
  1263. X# include "args.h"            /* for debugsw */
  1264. X
  1265. X/* # define DEBUG_READPR        /* dump all pr's */
  1266. X
  1267. X# ifndef UTMP_NO_HOST
  1268. X# define MUST_HAVE_TTY            /* run a bit faster */
  1269. X# endif /* UTMP_NO_HOST not defined */
  1270. X
  1271. Xextern struct info I;            /* namelist values from names.c */
  1272. Xextern struct user *ustruct();        /* from ustruct.c */
  1273. Xextern void u_cleanup();        /* from ustruct.c */
  1274. X
  1275. Xextern FTYPE kmem;            /* fd for /dev/kmem */
  1276. X                    /* (more under SunOS 4.0) */
  1277. X# if SunOS < 400
  1278. Xextern FTYPE mem;            /* fd for /dev/mem */
  1279. Xextern FTYPE swap;            /* fd for /dev/drum */
  1280. X                    /* from kmem.c */
  1281. X# endif /* SunOS < 400 */
  1282. X
  1283. XFORWARD LOCAL enum sig istate();
  1284. X
  1285. XLOCAL int nproc;            /* kernel nproc */
  1286. XLOCAL struct proc *aproc;        /* kernel virt addr of process table */
  1287. X
  1288. X/*
  1289. X * readpr finds and reads in the array pr, containing the interesting
  1290. X * parts of the proc and user tables for each live process.
  1291. X */
  1292. X
  1293. X# ifdef AIX3
  1294. X# define MAXPROC 512
  1295. X
  1296. XGLOBAL struct pr *readpr() {
  1297. X    int i, n;
  1298. X    struct pr *prvec;
  1299. X    struct procinfo pivec[MAXPROC];
  1300. X    register struct pr *prp;
  1301. X    register struct procinfo *pip;
  1302. X
  1303. X    n = getproc( pivec, MAXPROC, sizeof( struct procinfo ) );
  1304. X    if( n < 1 ) {
  1305. X        /* Check errno, report of MAXPROC too small!!! */
  1306. X    return( NULL );
  1307. X    }
  1308. X
  1309. X    prvec = (struct pr *) calloc( n+1, sizeof( struct pr ) );
  1310. X    if( prvec == NULL )
  1311. X    return( NULL );
  1312. X
  1313. X    prp = prvec;
  1314. X    for( i = 0, pip = pivec; i < n; i++, pip++ ) {
  1315. X    struct userinfo ui;
  1316. X
  1317. X    if( pip->pi_stat == 0 )
  1318. X        continue;
  1319. X
  1320. X    if( getuser( pip, sizeof( struct procinfo ),
  1321. X            &ui,  sizeof( struct userinfo ) ) < 0 )
  1322. X        continue;
  1323. X
  1324. X    prp->pr_uid = pip->pi_uid;
  1325. X    prp->pr_pid = pip->pi_pid;
  1326. X    prp->pr_ppid = pip->pi_ppid;
  1327. X    prp->pr_pgrp = pip->pi_pgrp;
  1328. X    prp->pr_stat = pip->pi_stat;
  1329. X    prp->pr_flag = pip->pi_flag;
  1330. X    prp->pr_wchan = pip->pi_wchan;
  1331. X
  1332. X    prp->pr_ttyp = ui.ui_ttyp;
  1333. X    prp->pr_ttyd = ui.ui_ttyd + ui.ui_ttympx;
  1334. X
  1335. X    strzcpy(prp->pr_cmd, ui.ui_comm, sizeof( ui.ui_comm ) );
  1336. X# ifdef DEBUG_READPR
  1337. X    dumppr( prp );
  1338. X# endif /* DEBUG_READPR defined */
  1339. X    prp++;
  1340. X    }
  1341. X    prp->pr_stat = 0;            /* mark end */
  1342. X
  1343. X# ifdef DEBUGSW
  1344. X    if( sw_debug )
  1345. X    printf("read %d processes\n", prp - prvec );
  1346. X# endif /* DEBUGSW defined */
  1347. X
  1348. X    /* realloc prvec to size? */
  1349. X    return( prvec );
  1350. X}
  1351. X
  1352. X# else  /* AIX3 not defined */
  1353. X
  1354. XGLOBAL struct pr *readpr() {
  1355. X    register struct pr *prp;        /* current pr entry */
  1356. X    register int i;            /* loop index */
  1357. X    struct user *upp;            /* pointer to upage(s) */
  1358. X    struct proc *mpp;            /* ptr to current process */
  1359. X    struct pr *prvec;
  1360. X    struct proc *allproc;        /* whole process table */
  1361. X# ifdef USG
  1362. X    struct var v;
  1363. X# endif /* USG defined */
  1364. X# if SunOS >= 410
  1365. X    struct sess sess;
  1366. X# endif /* SunOS >= 410 */
  1367. X
  1368. X    if( !ini_kmem() )            /* initialize /dev/kmem etc. */
  1369. X    return( NULL );
  1370. X
  1371. X# ifdef USG
  1372. X    KMEMREAD(I.info_v, &v, sizeof( v ) ); /* var struct */
  1373. X    nproc = v.v_proc;            /* size of proc table */
  1374. X    aproc = (struct proc *) I.info_proc; /* addr of proc table */
  1375. X# else  /* USG not defined */
  1376. X    KMEMREAD(I.info_nproc, &nproc, sizeof( nproc )); /* size of proc tbl */
  1377. X    KMEMREAD(I.info_proc,  &aproc, sizeof( aproc )); /* addr of proc tbl */
  1378. X# endif /* USG not defined */
  1379. X
  1380. X# ifdef DEBUG_READPR
  1381. X    printf("nproc %d aproc %#x\n", nproc, aproc );
  1382. X# endif /* DEBUG_READPR defined */
  1383. X
  1384. X    prvec = (struct pr *)calloc(nproc+1, sizeof(struct pr));/* allocate tbl */
  1385. X    if( prvec == NULL )
  1386. X    return( NULL );
  1387. X
  1388. X    allproc = (struct proc *) calloc(nproc, sizeof( struct proc ) );
  1389. X    KMEMREAD(aproc, allproc, nproc * sizeof( struct proc ) );
  1390. X    mpp = allproc;
  1391. X
  1392. X    prp = prvec;            /* pointer to dest block */
  1393. X    for( i = 0; i < nproc; i++, mpp++ ) { /* for all processes */
  1394. X    if( mpp->p_stat == 0 || mpp->p_stat == SZOMB ) /* a zombie or worse? */
  1395. X        continue;            /* forget it */
  1396. X
  1397. X# ifdef SSYS
  1398. X    if( mpp->p_flag & SSYS )    /* swapper or pager? */
  1399. X        continue;            /* flush */
  1400. X# endif /* SSYS defined */
  1401. X
  1402. X# ifdef SWEXIT
  1403. X    if( mpp->p_flag & SWEXIT )    /* exiting? */
  1404. X        continue;            /* nevermind. */
  1405. X# endif /* SWEXIT defined */
  1406. X
  1407. X# if defined(MUST_HAVE_TTY) && defined(P_TTYP)
  1408. X    /* avoid fetching ustruct needlessly */
  1409. X    if( mpp->p_ttyp == NULL )    /* no terminal pointer? */
  1410. X        continue;
  1411. X# endif /* defined(MUST_HAVE_TTY) && defined(P_TTYP) */
  1412. X
  1413. X# if SunOS >= 410
  1414. X    if( mpp->p_sessp == NULL ||
  1415. X       !KMEMREAD( (long)mpp->p_sessp, (char *)&sess, sizeof(sess) ) ) {
  1416. X# ifdef MUST_HAVE_TTY
  1417. X        continue;
  1418. X# else  /* MUST_HAVE_TTY not defined */
  1419. X        sess.s_ttyp = NULL;
  1420. X# endif /* MUST_HAVE_TTY not defined */
  1421. X    } /* no session or kmem read failed */
  1422. X# endif /* SunOS >= 410 */
  1423. X
  1424. X    if( (upp = ustruct( mpp )) == NULL ) /* get ustruct? */
  1425. X        continue;            /* no point. */
  1426. X
  1427. X# ifdef DEBUGSW
  1428. X    if( sw_debug && ((unsigned)upp->u_procp) != ((unsigned)(aproc + i)) )
  1429. X       printf("%%Funny u struct for pid %d u_procp %#x != %#x\n",
  1430. X          mpp->p_pid, upp->u_procp, (aproc + i) );
  1431. X# endif /* DEBUGSW defined */
  1432. X
  1433. X    /*
  1434. X     * WISH:
  1435. X     * check for master /etc/inetd /etc/rlogind etc???  (as a way to
  1436. X     * establish root of a process tree and avoid stray background
  1437. X     * processes on that tty) and keep only descendants thereof.
  1438. X     */
  1439. X
  1440. X# if 0 /* since we already have ustruct, just keep it! */
  1441. X# if defined(MUST_HAVE_TTY) && !defined(P_TTYP) && SunOS < 410
  1442. X    if( upp->u_ttyp == NULL )    /* no terminal pointer? */
  1443. X        continue;
  1444. X# endif /* defined(MUST_HAVE_TTY) && !defined(P_TTYP) && SunOS < 410 */
  1445. X# endif /* 0 */
  1446. X
  1447. X    /* save the interesting parts */
  1448. X    prp->pr_uid = mpp->p_uid;    /* user id */
  1449. X    prp->pr_pid = mpp->p_pid;    /* pid */
  1450. X    prp->pr_ppid = mpp->p_ppid;    /* parent pid */
  1451. X    prp->pr_pgrp = mpp->p_pgrp;    /* process group leader pid */
  1452. X    prp->pr_stat = mpp->p_stat;    /* state (1..6) */
  1453. X    prp->pr_flag = mpp->p_flag;    /* flags (esp swap) */
  1454. X    prp->pr_wchan = mpp->p_wchan;    /* wait address */
  1455. X
  1456. X# if SunOS >= 410
  1457. X    prp->pr_ttyp = sess.s_ttyp;
  1458. X    prp->pr_ttyd = sess.s_ttyd;
  1459. X# else  /* not SunOS >= 410 */
  1460. X# ifdef P_TTYP
  1461. X    prp->pr_ttyp = mpp->p_ttyp;    /* pointer to tty structure */
  1462. X# else  /* P_TTYP not defined */
  1463. X    prp->pr_ttyp = upp->u_ttyp;    /* pointer to tty structure or tpg */
  1464. X# endif /* P_TTYP not defined */
  1465. X    prp->pr_ttyd = upp->u_ttyd;    /* device number */
  1466. X# endif /* not SunOS >= 410 */
  1467. X    prp->pr_hup  = istate( upp->u_signal[SIGHUP] );
  1468. X    prp->pr_intr = istate( upp->u_signal[SIGINT] );
  1469. X    prp->pr_quit = istate( upp->u_signal[SIGQUIT]);
  1470. X    /* what you've all been waiting for... */
  1471. X    strzcpy(prp->pr_cmd, upp->u_comm, sizeof( upp->u_comm ) );
  1472. X
  1473. X# ifdef DEBUG_READPR
  1474. X    dumppr( prp );
  1475. X# endif /* DEBUG_READPR defined */
  1476. X    prp++;
  1477. X    } /* for i */
  1478. X    prp->pr_stat = 0;            /* mark end */
  1479. X    
  1480. X    /* WISH: realloc to shorten prvec? */
  1481. X
  1482. X    free( allproc );            /* free copy of process table */
  1483. X    u_cleanup();            /* cleanup ustruct reader */
  1484. X
  1485. X# ifdef DEBUGSW
  1486. X    if( sw_debug )
  1487. X    printf("read %d processes\n", prp - prvec );
  1488. X# endif /* DEBUGSW defined */
  1489. X
  1490. X    return( prvec );
  1491. X} /* readpr */
  1492. X
  1493. XLOCAL enum sig istate( x )        /* return signal handler state */
  1494. X# ifdef VOIDSIG
  1495. X    void (*x)();
  1496. X# else  /* VOIDSIG not defined */
  1497. X    int (*x)();
  1498. X# endif /* VOIDSIG not defined */
  1499. X{
  1500. X    if( x == SIG_DFL )
  1501. X        return( S_DEFAULT );        /* no handler */
  1502. X    else if( x == SIG_IGN )
  1503. X        return( S_IGNORE );        /* ignores interrupts */
  1504. X# ifdef SIG_HOLD
  1505. X    else if( x == SIG_HOLD )
  1506. X        return( S_HOLD );        /* interrupt held? */
  1507. X# endif /* SIG_HOLD defined */
  1508. X    else
  1509. X    return( S_CATCH );        /* has handler */
  1510. X} /* istate */
  1511. X
  1512. X# endif /* AIX3 not defined */
  1513. X
  1514. XGLOBAL waitstate_t waitstate( prp )    /* look at process wait states */
  1515. X    struct pr *prp;
  1516. X{
  1517. X# ifndef SHORT_TTYP            /* non-streams tty drivers... */
  1518. X    register struct tty *t;
  1519. X# endif /* SHORT_TTYP not defined */
  1520. X    register caddr_t w;
  1521. X
  1522. X    w = prp->pr_wchan;            /* get wait addr */
  1523. X    if( w == (caddr_t) 0 )        /* no wait? */
  1524. X    return( WS_RU );        /* runable */
  1525. X
  1526. X# ifndef SHORT_TTYP            /* non-streams tty drivers... */
  1527. X    t = prp->pr_ttyp;            /* get tty pointer */
  1528. X
  1529. X    if( w == (caddr_t) &t->t_rawq )    /* input wait */
  1530. X    return( WS_TI );
  1531. X    if( w == (caddr_t) &t->t_outq )    /* output wait */
  1532. X    return( WS_TO );
  1533. X    if( w >= (caddr_t) t && w < (caddr_t) (t+1) ) /* other terminal wait */
  1534. X    return( WS_TW );
  1535. X# endif /* SHORT_TTYP not defined */
  1536. X
  1537. X# ifdef USG
  1538. X# ifdef STREAMS
  1539. X    if( w == (caddr_t) I.info_pollwait ) /* poll(2) */
  1540. X    return( WS_SE );
  1541. X# endif /* STREAMS defined */
  1542. X# else  /* USG not defined */
  1543. X    if( w == (caddr_t) I.info_selwait )    /* select(2) */
  1544. X    return( WS_SE );
  1545. X# endif /* USG not defined */
  1546. X# if SunOS < 410
  1547. X    if( w == (caddr_t) I.info_u )    /* pause(2) */
  1548. X    return( WS_PA );
  1549. X# endif /* SunOS < 410 */
  1550. X    if( w >= (caddr_t) aproc && w <= (caddr_t) (aproc+nproc) ) /* wait(2)*/
  1551. X    return( WS_WA );
  1552. X
  1553. X    return( WS_SL );            /* something else */
  1554. X} /* waitstate */
  1555. X# endif /* Umax not defined */
  1556. X
  1557. X
  1558. X/*
  1559. X * Local variables:
  1560. X * comment-column: 40
  1561. X * End:
  1562. X */
  1563. END_OF_readpr.c
  1564. if test 9509 -ne `wc -c <readpr.c`; then
  1565.     echo shar: \"readpr.c\" unpacked with wrong size!
  1566. fi
  1567. # end of overwriting check
  1568. fi
  1569. if test -f ttyask.c -a "${1}" != "-c" ; then 
  1570.   echo shar: Will not over-write existing file \"ttyask.c\"
  1571. else
  1572. echo shar: Extracting \"ttyask.c\" \(10177 characters\)
  1573. sed "s/^X//" >ttyask.c <<'END_OF_ttyask.c'
  1574. X/*
  1575. X * ttyask.c -- front end for ttyloc -- ask about ttyplaces
  1576. X *
  1577. X * Copyright (C) 1986, 1990  Philip L. Budne
  1578. X *
  1579. X * This file is part of "Phil's Finger Program".
  1580. X *
  1581. X * This program is free software; you can redistribute it and/or modify
  1582. X * it under the terms of the GNU General Public License as published by
  1583. X * the Free Software Foundation; either version 1, or (at your option)
  1584. X * any later version.
  1585. X *
  1586. X */
  1587. X
  1588. X# ifndef lint
  1589. Xstatic char *rcsid = "$Id: ttyask.c,v 3.0 90/07/06 13:11:57 budd Rel $";
  1590. X# endif /* lint not defined */
  1591. X
  1592. X# include "finger.h"
  1593. X# include <pwd.h>
  1594. X# include <stdio.h>
  1595. X# include <ctype.h>
  1596. X# include <signal.h>
  1597. X# include <strings.h>
  1598. X# ifdef USG
  1599. X# include <termio.h>            /* POSIX too! */
  1600. X# else  /* USG not defined */
  1601. X# include <sgtty.h>
  1602. X# endif /* USG not defined */
  1603. X
  1604. X# include "ttylocfile.h"
  1605. X
  1606. Xextern char *getttytype();        /* from getttytype.c */
  1607. Xextern TTYLOC *findttyloc();        /* from readttylocfile.c */
  1608. X
  1609. X# define TTYLOC_PROG "ttyloc"        /* program to set ttylocs */
  1610. X# define TTYPLACES ".ttyplaces"        /* file to read */
  1611. X# define MAXTTP 256
  1612. X
  1613. X# ifndef DEFCYCLE
  1614. X# define DEFCYCLE 120            /* default cycle sleep time */
  1615. X# endif /* DEFCYCLE not defined */
  1616. X
  1617. X# ifndef MINCYCLE
  1618. X# define MINCYCLE 60            /* minimum allowed cycle/random time */
  1619. X# endif /* MINCYCLE not defined */
  1620. X
  1621. Xchar *pname;                /* name we were invoked as */
  1622. X
  1623. Xchar *non_hardwire_types[] = {        /* if you are this in /etc/ttytype */
  1624. X                    /* (or /etc/ttys in 4.3) you are */
  1625. X                    /* probably NOT hardwired */
  1626. X    "su",    "stupid",
  1627. X    "du",    "dialup",    "sd",    "D2",
  1628. X    "sa",    "network",
  1629. X    "un",    "unknown",
  1630. X    "se",    "ethernet",
  1631. X    "sw",    "switch",
  1632. X    "sp",    "plugboard",    "patch",
  1633. X    "sb",    "arpanet",
  1634. X    "sc",    "bussiplexer",
  1635. X# ifdef Umax
  1636. X    "",                    /* CALL connections come in like this*/
  1637. X                    /* if tty type not set */
  1638. X# endif /* Umax defined */
  1639. X# ifdef NON_HARDWIRE_TYPES
  1640. X    NON_HARDWIRE_TYPES ,
  1641. X# endif /* NON_HARDWIRE_TYPES defined */
  1642. X    NULL
  1643. X    };
  1644. X
  1645. Xstruct ttp {
  1646. X    char *t_name;
  1647. X    char *t_string;
  1648. X} ttp[MAXTTP];
  1649. Xint nttp;
  1650. X
  1651. X# ifdef USG
  1652. Xstruct termio old, new;
  1653. X# else  /* USG not defined */
  1654. Xstruct sgttyb old, new;
  1655. X# endif /* USG not defined */
  1656. X
  1657. XFORWARD LOCAL BOOL check_hardwire();
  1658. XFORWARD LOCAL void
  1659. X    setup(), restore(), readttp(), do_ttyask(), do_ttyplace(),
  1660. X    do_ttyrandom(), do_ttycycle(), sayit(), setit(), terpri(),
  1661. X    whine(), catcher(), checkwho();
  1662. X
  1663. Xint hardwire = 0;
  1664. Xint cycletime = 0;
  1665. Xchar mytty[ 512 ];
  1666. X
  1667. Xint main(argc, argv)
  1668. Xint argc;
  1669. Xchar *argv[];
  1670. X{
  1671. X    enum { F_NONE=0, F_TTYASK, F_TTYPLACE, F_TTYRANDOM, F_TTYCYCLE } function;
  1672. X    char *ttpfile;            /* -f argument */
  1673. X    int err, arg;
  1674. X    char *cp;                /* temp char ptr */
  1675. X
  1676. X    extern int getopt(), optind;
  1677. X    extern char *optarg;
  1678. X
  1679. X    err = 0;
  1680. X    pname = argv[0];
  1681. X    function = F_NONE;
  1682. X
  1683. X    if( (cp = rindex(pname, '/')) != NULL )
  1684. X    pname = cp + 1;
  1685. X    ttpfile = NULL;
  1686. X
  1687. X    while( (arg = getopt(argc, argv, "acf:hprt:")) != -1 ) {
  1688. X    switch( arg ) {
  1689. X    case 'f':
  1690. X        ttpfile = optarg;
  1691. X        break;
  1692. X    case 'h':
  1693. X        hardwire = 1;
  1694. X        break;
  1695. X    case 'c':
  1696. X        function = F_TTYCYCLE;
  1697. X        break;
  1698. X    case 'p':
  1699. X        function = F_TTYPLACE;
  1700. X        break;
  1701. X    case 'r':
  1702. X        function = F_TTYRANDOM;
  1703. X        break;
  1704. X    case 'a':
  1705. X        function = F_TTYASK;
  1706. X        break;
  1707. X    case 't':
  1708. X        cycletime = atoi( optarg );
  1709. X        break;
  1710. X
  1711. X    default:            /* ? or other junk */
  1712. X        err++;
  1713. X    } /* switch */
  1714. X    } /* while */
  1715. X
  1716. X    if( err > 0 )
  1717. X    whine("-a -c -r -h -t <time> -f <file>");
  1718. X
  1719. X    readttp( ttpfile );            /* read .ttyplaces (or other) file */
  1720. X
  1721. X    if( function == F_NONE ) {
  1722. X    if( strcmp(pname, "ttyplace") == 0 )
  1723. X        function = F_TTYPLACE;
  1724. X    else if( strcmp(pname, "ttyrandom") == 0 )
  1725. X        function = F_TTYRANDOM;
  1726. X    else if( strcmp(pname, "ttycycle") == 0 )
  1727. X        function = F_TTYCYCLE;
  1728. X    } /* F_NONE */
  1729. X
  1730. X    switch( function ) {
  1731. X    case F_NONE:
  1732. X    case F_TTYASK:
  1733. X    if( hardwire && check_hardwire() )
  1734. X        exit( 0 );
  1735. X    setup();
  1736. X    signal(SIGINT, catcher);
  1737. X    do_ttyask();
  1738. X    restore();
  1739. X    break;
  1740. X    case F_TTYPLACE:
  1741. X    if( optind < argc )
  1742. X        do_ttyplace( argv[optind] );
  1743. X    else
  1744. X        whine("must have string argument");
  1745. X    break;
  1746. X    case F_TTYRANDOM:
  1747. X    do_ttyrandom();
  1748. X    break;
  1749. X    case F_TTYCYCLE:
  1750. X    do_ttycycle();
  1751. X    break;
  1752. X    } /* switch */
  1753. X    return( 0 );            /* ANSI! */
  1754. X} /* main */
  1755. X
  1756. X# define LEN 200
  1757. XLOCAL void readttp( file )
  1758. Xchar *file;
  1759. X{
  1760. X    char fname[ LEN ];
  1761. X    struct passwd *pw;
  1762. X    FILE *f;
  1763. X
  1764. X    nttp = 0;
  1765. X    if( (pw = getpwuid( getuid() )) == NULL )
  1766. X    whine("no pw entry?");
  1767. X
  1768. X    if( file == NULL ) {
  1769. X    strcpy(fname, pw->pw_dir);
  1770. X    strcat(fname, "/");
  1771. X    strcat(fname, TTYPLACES);
  1772. X    file = fname;
  1773. X    }
  1774. X
  1775. X    if( (f = fopen(file, "r")) == NULL ) {
  1776. X    perror( file );
  1777. X    exit( 1 );
  1778. X    }
  1779. X
  1780. X    while( fgets(fname, LEN, f) != NULL ) {
  1781. X    register int i;
  1782. X    register char *cp;
  1783. X    char *p2;
  1784. X
  1785. X    i = strlen( fname );
  1786. X    if( i == 0 )
  1787. X        continue;
  1788. X
  1789. X    if( i < LEN - 1 )
  1790. X        fname[ i - 1 ] = EOS;
  1791. X
  1792. X    cp = fname;
  1793. X    while( *cp != EOS  && isspace( *cp ) )
  1794. X        cp++;
  1795. X    if( *cp == EOS )
  1796. X        continue;
  1797. X
  1798. X    while( *cp != EOS  && !isspace( *cp ) )
  1799. X        cp++;
  1800. X
  1801. X    if( *cp == EOS )
  1802. X        whine("no space on line: %s", fname);
  1803. X
  1804. X    *cp++ = EOS;
  1805. X    while( *cp != EOS  &&  isspace( *cp ) )
  1806. X        cp++;
  1807. X
  1808. X    if( *cp == EOS )
  1809. X        whine("no location for '%s'", fname);
  1810. X
  1811. X    ttp[ nttp ].t_name = p2 = malloc( strlen( fname ) + 1 );
  1812. X    strcpy(p2, fname);
  1813. X
  1814. X    ttp[ nttp ].t_string = p2 = malloc( strlen( cp ) + 1 );
  1815. X    strcpy(p2, cp);
  1816. X
  1817. X    nttp++;
  1818. X    } /* while */
  1819. X} /* readttp */
  1820. X
  1821. XLOCAL void do_ttyask() {
  1822. X    register int i, c;
  1823. X
  1824. X    if( cycletime > 0 )
  1825. X    signal(SIGALRM, catcher );
  1826. X    for(i = 0; i < nttp; i++ ) {
  1827. X    for( ; ; ) {
  1828. X        printf("--%s--", ttp[i].t_name );
  1829. X        if( cycletime > 0 )        /* time limit? */
  1830. X        alarm( cycletime );    /* reset the clock! */
  1831. X        c = getchar();
  1832. X        terpri();
  1833. X        if( c == EOF )
  1834. X        return;            /* unlikely in CBREAK */
  1835. X        switch( c & 0177 ) {
  1836. X        case '\03':            /* ^C */
  1837. X        case '\04':            /* ^D */
  1838. X        case 'Q':
  1839. X        case 'q':
  1840. X        return;
  1841. X        case ' ':
  1842. X        case 'Y':
  1843. X        case 'y':
  1844. X        alarm( 0 );
  1845. X        setit( i );
  1846. X        return;
  1847. X        case '?':
  1848. X        case 'h':
  1849. X        case 'H':
  1850. X        printf("space, Y, y       = yes\r\n");
  1851. X        printf("<del>, N, n, <bs> = no\r\n");
  1852. X        printf("?, H, h           = this\r\n");
  1853. X        printf("Q, q, ^c, ^d      = quit\r\n");
  1854. X        break;
  1855. X        case 0177:
  1856. X        case '\b':
  1857. X        case 'N':
  1858. X        case 'n':
  1859. X        goto no;    /* sigh (must break switch & for) */
  1860. X        break;
  1861. X        default:
  1862. X        printf("? for help\r\n");
  1863. X        break;
  1864. X        } /* case */
  1865. X    } /* for ever */
  1866. X    no: ;            /* break forever */
  1867. X    } /* for i */
  1868. X} /* do_ttyask */
  1869. X
  1870. XLOCAL int sort_item(a, b)
  1871. Xstruct ttp *a, *b;
  1872. X{
  1873. X    return( strcmp( a->t_name, b->t_name ) );
  1874. X} /* sort_item */
  1875. X
  1876. XLOCAL void sort_all() {
  1877. X    qsort(ttp, nttp, sizeof( struct ttp ), sort_item );
  1878. X} /* sort_all */
  1879. X
  1880. XLOCAL void do_ttyplace( name )
  1881. Xchar *name;
  1882. X{
  1883. X    register int i, it, len;
  1884. X
  1885. X    sort_all();
  1886. X    it = -1;
  1887. X    len = strlen( name );
  1888. X
  1889. X    for( i = 0; i < nttp; i++ ) {
  1890. X    if( strncmp(name, ttp[i].t_name, len) == 0 ) {
  1891. X        if( i+1 < nttp && strncmp(name, ttp[i+1].t_name, len) == 0 )
  1892. X        whine("ambiguous place '%s'", name);
  1893. X        else {
  1894. X        it = i;
  1895. X        break;
  1896. X        }
  1897. X    } /* if strncmp [i] */
  1898. X    } /* for */
  1899. X
  1900. X    if( it != -1 )
  1901. X    sayit( it );
  1902. X    else
  1903. X    whine("no place called '%s'", name);
  1904. X
  1905. X} /* do_ttyplace */
  1906. X
  1907. XLOCAL void do_ttyrandom() {
  1908. X    int i;
  1909. X    unsigned long seed;
  1910. X
  1911. X    if( cycletime > 0 && cycletime < MINCYCLE )
  1912. X    cycletime = MINCYCLE;
  1913. X
  1914. X    seed = getpid() + time( 0 );
  1915. X    for( ; ; ) {
  1916. X    seed = (seed * 11109 + 13849) & 0xffff;
  1917. X    i = seed % nttp;
  1918. X    setit( i );
  1919. X    if( cycletime == 0 )
  1920. X        return;
  1921. X    else
  1922. X        sleep( cycletime );
  1923. X    checkwho();
  1924. X    }
  1925. X} /* do_ttyrandom */
  1926. X
  1927. XLOCAL void do_ttycycle() {
  1928. X    int i;
  1929. X
  1930. X    if( cycletime < MINCYCLE )
  1931. X    cycletime = DEFCYCLE;
  1932. X    for( ; ; ) {
  1933. X    for( i = 0; i < nttp; i++ ) {
  1934. X        setit( i );
  1935. X        sleep( cycletime );
  1936. X        checkwho();
  1937. X    } /* for i */
  1938. X    } /* for ever */
  1939. X} /* do_ttycycle */
  1940. X
  1941. XLOCAL void sayit( i )
  1942. Xint i;
  1943. X{
  1944. X    printf("%s (%s)\n", ttp[ i ].t_name, ttp[ i ].t_string );
  1945. X    setit( i );
  1946. X} /* sayit */
  1947. X
  1948. XLOCAL void setit( i )
  1949. Xint i;
  1950. X{
  1951. X    char line[250];
  1952. X
  1953. X    line[0] = EOS;
  1954. X    sprintf(line, "%s %s", TTYLOC_PROG, ttp[i].t_string);
  1955. X
  1956. X    system( line );
  1957. X} /* setit */
  1958. X
  1959. XLOCAL void terpri() {
  1960. X    fputs("\r\n", stdout);        /* beware CBREAK mode */
  1961. X} /* terpri */
  1962. X
  1963. XLOCAL void whine(s,a)
  1964. Xchar *s, *a;
  1965. X{
  1966. X    char buf[ 100 ];
  1967. X    sprintf(buf, s, a);
  1968. X    fprintf(stderr, "%s: %s\n", pname, buf);
  1969. X    exit( 1 );
  1970. X} /* whine */
  1971. X
  1972. XLOCAL void catcher() {            /* here on signal */
  1973. X    restore();
  1974. X    exit( 1 );
  1975. X} /* catcher */
  1976. X
  1977. XLOCAL void setup() {
  1978. X# ifdef USG                /* POSIX too! */
  1979. X    ioctl( STD_INPUT, TCGETA, &old );
  1980. X    new = old;
  1981. X    new.c_cc[VMIN] = 1;
  1982. X    new.c_lflag &=~ECHO;
  1983. X    new.c_lflag &= ~ICANON;
  1984. X    ioctl( STD_INPUT, TCSETA, &new );
  1985. X# else  /* USG not defined */
  1986. X    gtty( STD_INPUT, &old);
  1987. X    new = old;
  1988. X    new.sg_flags &= ~(CBREAK|ECHO);
  1989. X    new.sg_flags |= RAW;
  1990. X    stty( STD_INPUT, &new);
  1991. X# endif /* USG not defined */
  1992. X} /* setup */
  1993. X
  1994. XLOCAL void restore() {
  1995. X# ifdef USG                /* POSIX too! */
  1996. X    ioctl( STD_INPUT, TCSETA, &old );
  1997. X# else  /* USG not defined */
  1998. X    stty( STD_INPUT, &old);
  1999. X# endif /* USG not defined */
  2000. X} /* restore */
  2001. X
  2002. X/****************************************************************/
  2003. X
  2004. XLOCAL void get_mytty() {
  2005. X    register char *tn, *tp;
  2006. X    extern char *ttyname();
  2007. X
  2008. X    if( mytty[0] != EOS )
  2009. X    return;
  2010. X
  2011. X    tn = ttyname( 0 );
  2012. X    if( tn == NULL )
  2013. X    return;
  2014. X    if( (tp = rindex( tn, '/')) != NULL )
  2015. X    tp++;
  2016. X    else
  2017. X    tp = tn;
  2018. X    strcpy( mytty, tp );
  2019. X}
  2020. X
  2021. XLOCAL void checkwho() {
  2022. X    if( getppid() == INIT_PID )
  2023. X    exit( 0 );
  2024. X}
  2025. X
  2026. XLOCAL BOOL check_hardwire() {
  2027. X    register char *ty, *cp;
  2028. X    register TTYLOC *tp;
  2029. X    register i;
  2030. X
  2031. X    get_mytty();
  2032. X
  2033. X    /* try to check line type from new ttyloc file */
  2034. X    if( readnewttylocfile() > 0 && (tp = findttyloc( mytty )) != NULL ) {
  2035. X    if( tp->t_type == LT_HARD || tp->t_type == LT_TTYLOC )
  2036. X        return( TRUE );
  2037. X    else
  2038. X        return( FALSE );
  2039. X    }
  2040. X
  2041. X    /* get terminal type (/etc/ttytype in 4.2; /etc/ttys in 4.3) */
  2042. X    if( (ty = getttytype(mytty)) == NULL )
  2043. X    return( FALSE );
  2044. X
  2045. X    /* look for type in list of known NON hardwired line types */
  2046. X    i = 0;
  2047. X    while( (cp = non_hardwire_types[ i ]) != NULL )
  2048. X    if( strcmp( cp, ty ) )
  2049. X        return( FALSE );        /* not a hardwire candidate */
  2050. X
  2051. X    return( TRUE );
  2052. X} /* check_hardwire */
  2053. X
  2054. X/*
  2055. X * Local variables:
  2056. X * comment-column: 40
  2057. X * End:
  2058. X */
  2059. END_OF_ttyask.c
  2060. if test 10177 -ne `wc -c <ttyask.c`; then
  2061.     echo shar: \"ttyask.c\" unpacked with wrong size!
  2062. fi
  2063. # end of overwriting check
  2064. fi
  2065. if test -f ustruct.c -a "${1}" != "-c" ; then 
  2066.   echo shar: Will not over-write existing file \"ustruct.c\"
  2067. else
  2068. echo shar: Extracting \"ustruct.c\" \(9355 characters\)
  2069. sed "s/^X//" >ustruct.c <<'END_OF_ustruct.c'
  2070. X/*
  2071. X * ustruct.c -- read user structure for finger
  2072. X *
  2073. X * Copyright (C) 1986, 1990  Philip L. Budne
  2074. X *
  2075. X * This file is part of "Phil's Finger Program".
  2076. X *
  2077. X * This program is free software; you can redistribute it and/or modify
  2078. X * it under the terms of the GNU General Public License as published by
  2079. X * the Free Software Foundation; either version 1, or (at your option)
  2080. X * any later version.
  2081. X *
  2082. X */
  2083. X
  2084. X/* WISH: Perhaps split into one file per O/S?
  2085. X * The copyright overhead would horrific!!
  2086. X */
  2087. X
  2088. X# ifndef lint
  2089. Xstatic char *rcsid = "$Id: ustruct.c,v 3.0 90/07/06 13:12:12 budd Rel $";
  2090. X# endif /* lint not defined */
  2091. X
  2092. X# include "finger.h"
  2093. X
  2094. X# ifndef Umax
  2095. X# include <stdio.h>
  2096. X
  2097. X# include "ustruct.h"
  2098. X
  2099. X# include "kmem.h"
  2100. X# include "info.h"            /* after finger.h */
  2101. X
  2102. X/*# define DEBUG_USTRUCT /**/
  2103. X
  2104. X# ifdef DEBUG_USTRUCT
  2105. X# define DEB(x) x
  2106. X# else  /* DEBUG_USTRUCT not defined */
  2107. X# define DEB(x)
  2108. X# endif /* DEBUG_USTRUCT not defined */
  2109. X
  2110. XLOCAL initialized = FALSE;
  2111. Xextern struct info I;            /* namelist values from names.c */
  2112. X
  2113. Xextern FTYPE kmem;            /* fd for /dev/kmem */
  2114. X# if SunOS < 400
  2115. Xextern FTYPE mem;            /* fd for /dev/mem */
  2116. Xextern FTYPE drum;            /* fd for /dev/drum */
  2117. X                    /* from kmem.c */
  2118. X
  2119. X# if !defined(NBPG) && defined(NBPP)
  2120. X# define NBPG NBPP
  2121. X# endif /* !defined(NBPG) && defined(NBPP) */
  2122. X
  2123. X# ifndef UPAGES
  2124. X# ifdef USIZE
  2125. X# define UPAGES USIZE            /* SVR3 */
  2126. X# else  /* USIZE not defined */
  2127. X# define UPAGES ((sizeof(struct user)+NBPG-1)/NBPG) /* ?? */
  2128. X# endif /* USIZE not defined */
  2129. X# endif /* UPAGES not defined */
  2130. X
  2131. X# ifndef ibm032                /* not IBM RT */
  2132. XLOCAL union {
  2133. X    struct user U;
  2134. X# ifdef NBPG
  2135. X    char upages[UPAGES][NBPG];
  2136. X# endif /* NBPG defined */
  2137. X} _u;
  2138. X
  2139. X# define u _u.U
  2140. X# else  /* ibm032 defined */
  2141. X
  2142. XLOCAL union {
  2143. X    struct {
  2144. X    char padding[ UPAGES*NBPG - sizeof( struct user ) ];
  2145. X    struct user U;
  2146. X    } _U;
  2147. X    char upages[UPAGES][NBPG];
  2148. X} _u;
  2149. X# define u _u._U.U
  2150. X# endif /* ibm032 defined */
  2151. X
  2152. X# if !defined(accel) && !defined(USG)
  2153. X# define NEED_UPAGEMAP            /* most BSD systems */
  2154. X# ifndef NEED_USRPT
  2155. XLOCAL struct pte upagemap[ UPAGES ];    /* pte's for ustruct */
  2156. X# else  /* NEED_USRPT defined */
  2157. XLOCAL struct pte upagemap[ NPTEPG ];    /* one page of pte's for ustruct */
  2158. XLOCAL struct pte *Usrptmap;        /* map for usrpt */
  2159. XLOCAL struct pte *usrpt;        /* user page map */
  2160. X# endif /* NEED_USRPT defined */
  2161. X# endif /* !defined(accel) && !defined(USG) */
  2162. X
  2163. X/****************************************************************/
  2164. X
  2165. XLOCAL void u_init() {
  2166. X# ifdef NEED_USRPT
  2167. X    /* assumes readnames() called */
  2168. X    Usrptmap = (struct pte *) I.info_Usrptmap;
  2169. X    usrpt = (struct pte *) I.info_usrpt;
  2170. X# endif /* NEED_USRPT defined */
  2171. X    initialized = TRUE;
  2172. X} /* u_init */
  2173. X# endif /* SunOS < 400 */
  2174. X
  2175. X/****************************************************************/
  2176. X
  2177. XGLOBAL void u_cleanup() {
  2178. X} /* u_cleanup */
  2179. X
  2180. X/****************************************************************/
  2181. X
  2182. X# undef HAVE_USTRUCT            /* sure wish #elif was ubiquitous!! */
  2183. X
  2184. X# if SunOS >= 400
  2185. X# define HAVE_USTRUCT
  2186. XLOCAL struct user *ustruct2( mpp )    /* find & read in the user structure */
  2187. Xstruct proc *mpp;
  2188. X{
  2189. X    return( kvm_getu( kmem, mpp ) );
  2190. X}
  2191. X# endif /* SunOS >= 400 */
  2192. X
  2193. X/****************/
  2194. X
  2195. X# ifdef sgi
  2196. X# define HAVE_USTRUCT
  2197. XLOCAL struct user *ustruct2( mpp )    /* find & read in the user structure */
  2198. Xstruct proc *mpp;
  2199. X{
  2200. X    if( syssgi( SGI_RDUBLK, mpp->p_pid, &u, sizeof( _u ) ) < 0 )
  2201. X    return( NULL );
  2202. X    return( &u );
  2203. X}
  2204. X# endif /* sgi defined */
  2205. X
  2206. X# ifdef SYSI86                /* Interactive 386/ix  */
  2207. X# define HAVE_USTRUCT
  2208. XLOCAL struct user *ustruct2( mpp )    /* find & read in the user structure */
  2209. Xstruct proc *mpp;
  2210. X{
  2211. X    if( sysi86( RDUBLK, mpp->p_pid, &u, sizeof( _u ) ) < 0 )
  2212. X    return( NULL );
  2213. X    return( &u );
  2214. X}
  2215. X# endif /* SYSI86 defined */
  2216. X
  2217. X# ifdef UmaxV
  2218. X# define HAVE_USTRUCT
  2219. X
  2220. X# ifdef ns32302                /* on DPC (32032) BPP is a lie */
  2221. X# define NPPP 4                /* Each "page" is 4 physical pages */
  2222. X# else  /* ns32302 not defined */
  2223. X# define NPPP 1                /* APC: pages per physical page */
  2224. X# endif /* ns32302 not defined */
  2225. X
  2226. XLOCAL struct user *ustruct2( mpp )    /* find & read in the user structure */
  2227. Xstruct proc *mpp;
  2228. X{
  2229. X    int i;
  2230. X    for( i = 0; i < USIZE; i++ ) {
  2231. X    int k;
  2232. X    for( k = 0; k < NPPP; k++ ) {
  2233. X        /* upages never swapped? */
  2234. X        if( !mpp->p_ubptbl[i].pgm[k].pg_v ||
  2235. X           !kread( mem,
  2236. X              mpp->p_ubptbl[i].pgm[k].pg_pfn << PNUMSHFT,
  2237. X              ((char *)_u.upages[i]) + k * NBPP/NPPP,
  2238. X              NBPP/NPPP ) )
  2239. X           return( NULL );
  2240. X    } /* for k */
  2241. X    } /* for i */
  2242. X    return( &u );
  2243. X}
  2244. X# endif /* UmaxV defined */
  2245. X
  2246. X/****************/
  2247. X
  2248. X# ifdef AIX_RT
  2249. X# define HAVE_USTRUCT
  2250. XLOCAL struct user *ustruct2( mpp )    /* find & read in the user structure */
  2251. Xstruct proc *mpp;
  2252. X{
  2253. X    int i, cc;
  2254. X
  2255. X    /* seems that segids[n] always == n, but make sure!! */
  2256. X    for( i = 0; i < mpp->p_segs.count; i++ )
  2257. X    if( mpp->p_segs.p_segids[i].seg_reg == STACKSEG )
  2258. X        break;
  2259. X
  2260. X    if( i == mpp->p_segs.count || lseek( mem, I.info_u, 0 ) < 0 )
  2261. X    return( NULL );
  2262. X
  2263. X    i = mpp->p_segs.p_segids[i].seg_id;    /* get VRM segment ID */
  2264. X    cc = readx( mem, &_u, sizeof( _u ), i ); /* funky 4 arg read!! */
  2265. X    if( cc < sizeof( _u ) )
  2266. X    return( NULL );
  2267. X    return( &u );
  2268. X}
  2269. X# endif /* AIX_RT defined */
  2270. X
  2271. X# ifdef AIX3
  2272. X# define HAVE_USTRUCT
  2273. X/* calls getuser directly in readpr() */
  2274. X# endif /* AIX3 defined */
  2275. X
  2276. X/****************/
  2277. X
  2278. X# ifdef AIX_PS2                /* yet another OS named AIX! */
  2279. X# define HAVE_USTRUCT
  2280. XLOCAL struct user *ustruct2( mpp )    /* find & read in the user structure */
  2281. Xstruct proc *mpp;
  2282. X{
  2283. X    int i;
  2284. X
  2285. X    if( (mpp->p_flag & SLOAD) == 0 ) {    /* process is swapped */
  2286. X    for( i = 0; i < UPAGES; i++ ) {
  2287. X        printf("p_uswaddr[%d].dbd_type = %d\n",
  2288. X        i, mpp->p_uswaddr[i].dbd_type );
  2289. X    }
  2290. X    }
  2291. X
  2292. X    for( i = 0; i < UPAGES; i++ ) {
  2293. X    long upage;
  2294. X
  2295. X    upage = ctob( PFN( mpp->p_uaddr[i] ) );
  2296. X    DEB( printf("  upage %d/%d at %#x\n", i+1, UPAGES, upage ) );
  2297. X    if( ! kread(mem, upage, _u.upages[i], NBPG) )
  2298. X        return( NULL );
  2299. X    }
  2300. X}
  2301. X# endif /* AIX_PS2 defined */
  2302. X
  2303. X/****************
  2304. X * BSD systems
  2305. X */
  2306. X
  2307. X# if !defined(USG) && !defined(HAVE_USTRUCT)
  2308. X# define HAVE_USTRUCT
  2309. XLOCAL struct user *ustruct2( mpp )    /* find & read in the user structure */
  2310. Xstruct proc *mpp;
  2311. X{
  2312. X    int i;                /* loop index */
  2313. X# ifdef NEED_USRPT
  2314. X    struct pte indirpte, *pte, *pumap;
  2315. X# endif /* NEED_USRPT defined */
  2316. X
  2317. X    if( !initialized )
  2318. X    u_init();            /* initialize ustruct reader */
  2319. X
  2320. X    if( (mpp->p_flag & SLOAD) == 0 ) {    /* process is swapped */
  2321. X    long addr;            /* disk address of ustruct */
  2322. X
  2323. X    addr = dtob(mpp->p_swaddr);    /* disk to bytes */
  2324. X    DEB( printf(" ustruct from drum %#x\n", addr ) );
  2325. X    if( ! kread(drum, addr, &u, sizeof(_u)) ) /* read from drum */
  2326. X        return( NULL );
  2327. X    return( &u );
  2328. X    } /* is swapped */
  2329. X
  2330. X
  2331. X    /****************************************************************
  2332. X     * process loaded in core:
  2333. X     */
  2334. X
  2335. X# ifdef accel
  2336. X    /*
  2337. X     * amazingly easy... p_addr is kernel address!!
  2338. X     */
  2339. X    if( ! KMEMREAD( mpp->p_addr, &u, sizeof(u)) ) /* read from kmem */
  2340. X    return( NULL );
  2341. X
  2342. X# else  /* accel not defined */
  2343. X
  2344. X# ifndef NEED_USRPT
  2345. X# ifdef sequent
  2346. X# define p_addr p_pttop
  2347. X# endif /* sequent defined */
  2348. X    DEB( printf(" p_addr: %#x\n", mpp->p_addr ) );
  2349. X    if( ! KMEMREAD( mpp->p_addr, upagemap, sizeof(upagemap)) )
  2350. X    return( NULL );
  2351. X# else  /* NEED_USRPT defined */
  2352. X    /*
  2353. X     * p_addr does not work on IBM RT ACIS/4.3;
  2354. X     * read page table entry for uarea page map page from user pagemap
  2355. X     */
  2356. X
  2357. X    pte = &Usrptmap[ btokmx(mpp->p_p0br) + mpp->p_szpt - 1 ];
  2358. X    DEB( printf(" indirpte pte at %#x\n", pte ) );
  2359. X    if( ! KMEMREAD( (long)pte, &indirpte, sizeof(indirpte)) )
  2360. X    return( NULL );
  2361. X
  2362. X    /****************************************************************
  2363. X     * read one page of ptes for user area page table
  2364. X     */
  2365. X# ifndef ibm032
  2366. X    /* for vax, sun: */
  2367. X    pumap = (struct pte *) ctob( indirpte.pg_pfnum );
  2368. X# else  /* ibm032 defined */
  2369. X# define REDPAGES 2            /* this is sick */
  2370. X    pumap = ((struct pte *) ctob( indirpte.pg_pfnum + 1))  - (UPAGES+REDPAGES);
  2371. X# endif /* ibm032 defined */
  2372. X
  2373. X    DEB( printf(" upagemap at %#x\n", pumap ) );
  2374. X    if( ! kread(mem, pumap, upagemap, sizeof(upagemap)) )
  2375. X    return( NULL );
  2376. X# endif /* NEED_USRPT defined */
  2377. X
  2378. X    /* read actual user structure pages */
  2379. X    for( i = 0; i < UPAGES; i++ ) {    /* get u area pages */
  2380. X    long upage;            /* address of upage pagemap */
  2381. X
  2382. X# ifndef NEED_USRPT
  2383. X    upage = ctob( upagemap[i].pg_pfnum );
  2384. X# else  /* NEED_USRPT defined */
  2385. X# ifdef ibm032
  2386. X    upage = ctob( upagemap[i+REDPAGES].pg_pfnum );
  2387. X# else  /* ibm032 not defined */
  2388. X    upage = ctob( upagemap[i+NPTEPG-UPAGES].pg_pfnum ); /* vax, sun */
  2389. X# endif /* ibm032 not defined */
  2390. X# endif /* NEED_USRPT defined */
  2391. X    DEB( printf("  upage %d/%d at %#x\n", i+1, UPAGES, upage ) );
  2392. X    if( ! kread(mem, upage, _u.upages[i], NBPG) )
  2393. X        return( NULL );
  2394. X    } /* for i */
  2395. X# endif /* accel not defined */
  2396. X    return( &u );
  2397. X} /* ustruct2 */
  2398. X# endif /* !defined(USG) && !defined(HAVE_USTRUCT) */
  2399. X
  2400. X/****************/
  2401. X
  2402. X# ifndef HAVE_USTRUCT
  2403. XLOCAL struct user *ustruct2( mpp )    /* find & read in the user structure */
  2404. Xstruct proc *mpp;
  2405. X{
  2406. X    return( NULL );            /* no generic USG solution */
  2407. X} /* ustruct2 */
  2408. X# endif /* HAVE_USTRUCT not defined */
  2409. X
  2410. X/****************/
  2411. X
  2412. XGLOBAL struct user *ustruct( mpp )
  2413. Xstruct proc *mpp;
  2414. X{
  2415. X    struct user *upp;
  2416. X    upp = ustruct2( mpp );
  2417. X    DEB( if( upp != NULL ) printf(" u_ttyd: %#x\n", upp->u_ttyd ) );
  2418. X    return( upp );
  2419. X} /* ustruct */
  2420. X# endif /* Umax not defined */
  2421. X
  2422. X/*
  2423. X * Local variables:
  2424. X * comment-column: 40
  2425. X * End:
  2426. X */
  2427. END_OF_ustruct.c
  2428. if test 9355 -ne `wc -c <ustruct.c`; then
  2429.     echo shar: \"ustruct.c\" unpacked with wrong size!
  2430. fi
  2431. # end of overwriting check
  2432. fi
  2433. echo shar: End of archive 5 \(of 7\).
  2434. cp /dev/null ark5isdone
  2435. MISSING=""
  2436. for I in 1 2 3 4 5 6 7 ; do
  2437.     if test ! -f ark${I}isdone ; then
  2438.     MISSING="${MISSING} ${I}"
  2439.     fi
  2440. done
  2441. if test "${MISSING}" = "" ; then
  2442.     echo You have unpacked all 7 archives.
  2443.     rm -f ark[1-9]isdone
  2444. else
  2445.     echo You still need to unpack the following archives:
  2446.     echo "        " ${MISSING}
  2447. fi
  2448. ##  End of shell archive.
  2449. exit 0
  2450.  
  2451.